Cuckoo generates mocks of your Swift protocols and classes at build time, and gives tests a Mockito-style API to stub them and verify their calls:
@Test(.cuckoo())
func welcomesTheUser() {
let greeter = MockGreeter()
stub(greeter) { stub in
when(stub.greet(name: any())).thenReturn("Hello")
}
let screen = WelcomeScreen(greeter: greeter)
#expect(screen.title == "Hello")
verify(greeter).greet(name: "Ann")
}
Cuckoo has two parts: the Cuckoo library that tests link against, and a generator that reads your sources and
writes a mock for each protocol and class. A SwiftPM or Xcode build plugin runs the generator on every build, so the
mocks always match the code.
Mocks work by protocol conformance and subclassing, so only what can be overridden can be mocked: protocols, and
the non-final members of classes. Structs, final and private declarations, and global functions can't be;
put a protocol in front of them.
- Swift 6 concurrency: a mock keeps the isolation of the type it mocks.
@MainActorand global-actor protocols get isolated mocks,actorprotocols get actor mocks, andSendabletypes get checkedSendablemocks. - Swift Testing and XCTest, with a
.cuckoo()trait for per-test configuration. - Async and throwing members, typed throws,
inout,~Copyablearguments and parameter packs. - Generics, associated types, inheritance, static and class members, and subscripts.
- Spies, default implementations, argument captors, in-order verification and
eventuallyfor asynchronous code. - Failure messages that show each call a member received and the argument that didn't match.
- Swift 6.2 or later (Xcode 26 or later). The Swift 6 language mode is recommended; the mocks also compile in the Swift 5 mode, which CI doesn't test.
- iOS 17, macOS 14, tvOS 17 or watchOS 10, or Linux.
The documentation is a DocC catalog in Source/Cuckoo.docc. Build it with
scripts/build-docs.sh, or open the package in Xcode and choose Product > Build Documentation.
-
Getting started: add the package and a build plugin, and write a first test.
-
The Cuckoofile: every option of
Cuckoofile.toml. -
Stubbing and verification: stubs, spies, default implementations, static members, verification, argument captors.
-
Matching arguments and calls: matchers for arguments, collections and call counts.
-
Cookbook: MainActor view models, background work, actors, Swift Testing suites, slow calls, Objective-C dependencies and completion handlers.
-
Migrating from Cuckoo 2: what changes for an existing suite.
The list of changes is in the changelog.
Cuckoo is open for everyone and we'd like you to help us make the best Swift mocking library. For Cuckoo development, follow these steps:
- Clone the Cuckoo repository.
- Open
Package.swiftin Xcode, or runswift test(on macOS or Linux). It runs the generator's unit and snapshot tests and the runtime tests, with mocks the plugin generates fromCuckoofile.toml. - To test on a simulator, run
scripts/install-scheme.sh, then use theCuckooTestsscheme withxcodebuild -skipPackagePluginValidation. - Peek around or file a pull request with your changes.
The package consists of two parts - runtime and code generator:
Source- runtime sources and the DocC catalogGenerator- the generator (CuckooGenerator), its build plugin and its testsTests- tests for the runtime part, in Swift 6 mode like everything else
Thank you for your help!
Cuckoo is available under the MIT License.