Contents

jonreid/outputtracking

**Replace mocks with tracked output in your Swift tests.**

Contents

Quick Start Core Components OutputRegistry OutputLog Usage Pattern Installation * About the Author<!-- endToc -->

Why OutputTracking Instead of Mocks?

  • More realistic — Tests verify actual behavior, not fake implementations
  • Less brittle — Tests don’t break when implementation details change
  • Easier maintenance — No complex mock setups or verification chains
  • Better coverage — Tests exercise real code paths

Quick Start

import OutputTracking
 
// Create a service that tracks its output
class NetworkService {
    private let outputRegistry = OutputRegistry()
    
    func fetchData(from url: String) async {
        await outputRegistry.track(url)
        // ... actual network logic
    }
    
    func trackOutput() async -> OutputLog {
        await outputRegistry.registeredLog()
    }
}
 
// In your tests
@Test("Network service fetches correct URL")
func test_fetchData_url() async throws {
    let sut = NetworkService()
    let output = await sut.trackOutput()
    
    await sut.fetchData(from: "https://api.example.com")
    
    let urls = try #require(output.data as? [String])
    #expect(urls == ["https://api.example.com"])
}

(Wondering how to prevent an actual network call during testing? That’s where nullables come in. Instead of directly instantiating NetworkService, we would use two factory methods: create() for full functionality, and createNull() that “disables all external communication, but behaves normally in every other respect.”)

Core Components

OutputRegistry

An actor that manages multiple output logs and broadcasts data to all active logs.

OutputLog

A collection that captures tracked data. Each log receives all data broadcast by its registry.

Usage Pattern

  1. Create an OutputRegistry in your type
  2. Call await outputRegistry.track(data) when interesting events happen
  3. Tests ask the type for an OutputLog before exercising the system
  4. Verify the captured data in your tests

Installation

Add to your Package.swift dependencies:

.package(url: "https://github.com/jonreid/OutputTracking.git", from: "1.0.0")

Then add "OutputTracking" to your production code dependencies, not your test dependencies.

About the Author

Jon Reid is the author of iOS Unit Testing by Example. Find more at Quality Coding.

[[Bluesky]](https://bsky.app/profile/qualitycoding.org) [[Mastodon]](https://iosdev.space/@qcoding) [[YouTube]](https://www.youtube.com/@QualityCoding) [[GitHub]](https://github.com/jonreid)

Package Metadata

Repository: jonreid/outputtracking

Default branch: main

README: README.md