SwiftMock 0.0.3

SwiftMock 0.0.3

LangLanguage SwiftSwift
License MIT
ReleasedLast Release Nov 2018
SPMSupports SPM

Maintained by Matthew Flint.

SwiftMock 0.0.3

  • By
  • Matthew Flint


CI Status Version License Platform

SwiftMock is a first attempt at a mocking/stubbing framework for Swift 2.0. It's at an early stage of development, but may be usable.

I'm posting it publicly to get some feedback on its API, as used in your tests.

Note: This is a Swift 2.0 project, so requires Xcode 7.0 to build.


  • There's some boiler-plate code needed to create mocks. See MockExampleCollaborator for an example, and the Usage section below
  • No support (yet) for stubbing, explicitly rejecting calls, call counts or nice mocks
  • No support (yet) for "any value" matchers
  • Not all failure scenarios can report exactly where the failure occurred


There's an example test file called ExampleTests.swift. Look there for some tests that can be run. This tests a class Example against a mocked collaborator ExampleCollaborator.

The examples below assume we're mocking this protocol:

protocol Frood {
    func voidFunction(value: Int)
    func function() -> String
    func anotherFunction(value: String)

In your test code, you'll need to create a MockFrood, which extends Frood and adopts Mock. The mock creates a MockCallHandler, and forwards all calls to it:

public class MockFrood: Frood, Mock {
    let callHandler: MockCallHandler
    init(testCase: XCTestCase) {
        callHandler = MockCallHandlerImpl(testCase)
    override func voidFunction(int: Int) {
        // the first argument is the value returned by the mock
        // while setting expectations. In this case, we can use nil
        // as it returns Void
        callHandler.accept(nil, functionName: __FUNCTION__, args: int)
    override func function() -> String {
        // here, the return type is String, so the first argument
        // is a String. Any String will do.
        return callHandler.accept("", functionName: __FUNCTION__, args: nil) as! String

    override func anotherFunction(value: String) {
        callHandler.accept(nil, functionName: __FUNCTION__, args: value)

Out of the box, SwiftMock can match the following types:

  • String / String?
  • Int / Int?
  • Double / Double?
  • Array / Array?
  • Dictionary / Dictionary?
  • raise an issue if I'm missing any common types

Given that Swift doesn't have reflection, SwiftMock can't magically match your custom types, so you'd need to make an extension for MockMatcher which adopts MockMatcherExtension:

extension MockMatcher: MockMatcherExtension {
    public func match(item1: Any?, _ item2: Any?) -> Bool {
        switch item1 {
        case let first as MyCustomType:
            if let second = item2 as? MyCustomType {
                // custom matching code here //
                return true
            return false

I'd probably put the mock objects and custom matcher code in a separate group in the test part of my project.

Currently-supported syntax

// expect a call on a void function
// expect a call on a function which returns a String value
// expect a call on a function which returns a String value, and also call a closure
// expect a call on a function, use a closure to return a String value
mockObject.expect().call(mockObject.function()).andReturnValue({ () in
    return "dent"

Future stuff

// expect a call with any String parameter
// expect a call with any String parameter, and capture it using a block
mockObject.expect().call(mockObject.anotherFunction(mockObject.anyString())).andCapture{ (parameters: Dictionary) in
    // parameters dictionary contains the function parameters
// stub a call
// reject a call

Mocks are currently strict, but with nice mocks we could also support the newer "verify expectations after mocking" style:

// prod the system under test

// then verify that a function was called

... but I don't suppose we'd be able to feed return values back into the system. Hmm...


  • Xcode 7
  • XCTest


SwiftMock is available through CocoaPods. To install it, simply add the following line to your Podfile against your test target:

pod "SwiftMock"


Issues and pull-requests most welcome - especially feedback on any Bad Swift you might find :-)


Matthew Flint, [email protected]


SwiftMock is available under the MIT license. See the LICENSE file for more info.