Swift 6.1 macOS 13+ MIT License
Stop writing mocks.
Start testing.
SwiftMock automatically generates mock implementations for your Swift protocols. Mark protocols with /// @mockable and let SwiftMock handle the boilerplate.
$ swiftmock –source ./Sources –output ./Tests/Mocks/GeneratedMocks.swift▋
✓ Found 12 mockable protocols
✓ Generated mocks in 0.3s
⏱
Time Consuming
Hours spent writing boilerplate mock code instead of actual tests
🔄
Repetitive Work
Same patterns repeated across every protocol in your codebase
⚠️
Error Prone
Manual mock updates often fall out of sync with protocol changes
The Solution
Automatic mock generation
SwiftMock scans your Swift source files, finds protocols marked with /// @mockable, and generates complete mock im…
Swift 6.1 macOS 13+ MIT License
Stop writing mocks.
Start testing.
SwiftMock automatically generates mock implementations for your Swift protocols. Mark protocols with /// @mockable and let SwiftMock handle the boilerplate.
$ swiftmock –source ./Sources –output ./Tests/Mocks/GeneratedMocks.swift▋
✓ Found 12 mockable protocols
✓ Generated mocks in 0.3s
⏱
Time Consuming
Hours spent writing boilerplate mock code instead of actual tests
🔄
Repetitive Work
Same patterns repeated across every protocol in your codebase
⚠️
Error Prone
Manual mock updates often fall out of sync with protocol changes
The Solution
Automatic mock generation
SwiftMock scans your Swift source files, finds protocols marked with /// @mockable, and generates complete mock implementations with call tracking, argument capture, and customizable handlers.
- ✓ Zero manual mock maintenance
- ✓ Always in sync with your protocols
- ✓ Incremental builds for speed
- ✓ Works with your existing workflow
Before
// Manually written mock
class UserServiceMock: UserService {
var fetchCallCount = 0
var fetchArgs: [String] = []
var fetchHandler: ((String) -> User)?
func fetch(id: String) -> User {
fetchCallCount += 1
fetchArgs.append(id)
return fetchHandler!(id)
}
// ... repeat for every method
}
→
After
/// @mockable
protocol UserService {
func fetch(id: String) -> User
}
// That's it! ✨
📊
Call Tracking
Every method gets a call counter. Verify exactly how many times your code called each method.
XCTAssertEqual(mock.fetchUserCallCount, 1)
📦
Argument Capture
All arguments are captured in arrays. Inspect exactly what values were passed to each call.
XCTAssertEqual(mock.fetchUserReceivedArguments.first, "123")
🎛
Custom Handlers
Define custom behavior for each method. Return different values, throw errors, or trigger side effects.
mock.fetchUserHandler = { id in User(id: id) }
⚡️
Async & Throws
Full support for async methods, throwing functions, and complex return types.
func deleteUser(id: String) async throws
🔄
Incremental Builds
Smart caching skips regeneration when source files haven’t changed. Blazing fast CI builds.
swiftmock -s ./Sources -o ./Mocks.swift
📁
Flexible Output
Generate all mocks in one file or separate files per protocol. Organize however you prefer.
swiftmock --per-file -o ./Tests/Mocks/
1
Mark your protocols
Add /// @mockable above any protocol you want to mock.
/// @mockable
protocol UserService {
func fetchUser(id: String) throws -> User
func deleteUser(id: String) async throws
func updateUserName(_ name: String, for id: String)
}
2
Run SwiftMock
Execute the command to scan your source files and generate mocks.
$ swiftmock --source ./Sources --output ./Tests/Mocks/GeneratedMocks.swift
3
Write your tests
Use the generated mocks in your tests with full call tracking and custom handlers.
func testUserFetch() {
let mockService = UserServiceMock()
// Set up mock behavior
mockService.fetchUserHandler = { id in
return User(id: id, name: "Test User")
}
// Execute test
let user = try mockService.fetchUser(id: "123")
// Verify
XCTAssertEqual(mockService.fetchUserCallCount, 1)
XCTAssertEqual(mockService.fetchUserReceivedArguments.first, "123")
XCTAssertEqual(user.name, "Test User")
}
Generated Code
See what SwiftMock generates
SwiftMock produces clean, readable mock classes that follow Swift best practices. Each method gets call tracking, argument capture, and a customizable handler.
- ✓ Public access for cross-module testing
- ✓ Call count tracking per method
- ✓ Full argument history capture
- ✓ Customizable handlers with type safety
- ✓ Fatal error if handler not set (catches test setup errors)
public final class UserServiceMock: UserService {
public init() {}
// MARK: - fetchUser
var fetchUserCallCount = 0
var fetchUserHandler: ((String) throws -> User)?
var fetchUserReceivedArguments: [String] = []
func fetchUser(id: String) throws -> User {
fetchUserCallCount += 1
fetchUserReceivedArguments.append(id)
guard let handler = fetchUserHandler else {
fatalError("fetchUserHandler must be set")
}
return try handler(id)
}
}
| Flag | Short | Description |
|---|---|---|
--source | -s | Required. Root directory to scan for Swift files |
--output | -o | Required. Output file path for generated mocks |
--exclude | -e | Comma-separated list of folders to exclude |
--verbose | -v | Enable verbose output for debugging |
--per-file | Generate a separate mock file for each protocol | |
--force | Force generation on every run (skip incremental check) |
Xcode Integration
Automate with build phases
Add SwiftMock to your Xcode build phases to automatically regenerate mocks whenever your protocols change. Your mocks will always be in sync.
- Select your test target in Xcode
- Go to Build Phases → New Run Script Phase
- Add the script shown on the right
- Build your project — mocks are regenerated automatically!
if which swiftmock >/dev/null; then
swiftmock \
-s "$SRCROOT/Sources" \
-o "$SRCROOT/Tests/Mocks/GeneratedMocks.swift"
else
echo "warning: SwiftMock not installed"
fi
Add SwiftMock to your Package.swift dependencies:
dependencies: [
.package(
url: "https://github.com/yourusername/SwiftMock.git",
from: "1.0.0"
)
]
Clone the repository and build the release binary:
$ git clone https://github.com/yourusername/SwiftMock.git
$ cd SwiftMock
$ swift build -c release
$ cp .build/release/swiftmock /usr/local/bin/
Ready to simplify your testing?
Stop writing mock boilerplate. Start shipping features.