Mockingbird Documentation 0.18.0

Class Stubbing​Manager

public class StubbingManager<DeclarationType: Declaration, InvocationType, ReturnType>  

An intermediate object used for stubbing declarations returned by given.

Nested Types

StubbingManager.TransitionStrategy

When to use the next chained implementation provider.

Methods

will​Forward​ToSuper()

@discardableResult
  func willForwardToSuper() -> Self  

Forward calls for a specific declaration to the superclass.

Use willForwardToSuper on class mock declarations to call the superclass implementation when receiving a matching invocation. Superclass forwarding persists until removed with clearStubs or shadowed by a forwarding target that was added afterwards.

class Bird {
  let name: String
  init(name: String) { self.name = name }
}

// `BirdMock` subclasses `Bird`
let bird: BirdMock = mock(Bird.self).initialize(name: "Ryan")

given(bird.name).willForwardToSuper()
print(bird.name)  // Prints "Ryan"

The mocked type must be a class. Adding superclass forwarding to mocked protocol declarations is a no-op.

// Not a class
protocol AbstractBird {
  var name: String { get }
}

let bird = mock(AbstractBird.self)
given(bird.name).willForwardToSuper()
print(bird.name)  // Error: Missing stubbed implementation

Parameters

object

An object that should handle forwarded invocations.

will​Forward(to:​)

@discardableResult
  func willForward<T>(to object: T) -> Self  

Forward calls for a specific declaration to an object.

Objects are strongly referenced and receive forwarded invocations until removed with clearStubs. Targets added afterwards have a higher precedence and only pass calls down the forwarding chain if unable handle the invocation, such as when the target is unrelated to the mocked type.

class Crow: Bird {
  let name: String
  init(name: String) { self.name = name }
}

given(bird.name).willForward(to: Crow(name: "Ryan"))
print(bird.name)  // Prints "Ryan"

// Additional targets take precedence
given(bird.name).willForward(to: Crow(name: "Sterling"))
print(bird.name)  // Prints "Sterling"

Concrete stubs always have a higher priority than forwarding targets, regardless of the order they were added.

given(bird.name).willReturn("Ryan")
given(bird.name).willForward(to: Crow(name: "Sterling"))
print(bird.name)  // Prints "Ryan"

Objects must inherit from the mocked type to handle forwarded invocations, even if the declaration is identical. Adding an unrelated type as a forwarding target is a no-op.

// Not a `Bird`
class Person {
  var name = "Ryan"
}

given(bird.name).willForward(to: Person())
print(bird.name)  // Error: Missing stubbed implementation

Parameters

object T

An object that should handle forwarded invocations.

will​Return(_:​)

@discardableResult
  public func willReturn(_ value: ReturnType) -> Self  

Stub a mocked method or property by returning a single value.

Stubbing allows you to define custom behavior for mocks to perform.

given(bird.doMethod()).willReturn(someValue)
given(bird.property).willReturn(someValue)

Match exact or wildcard argument values when stubbing methods with parameters. Stubs added later have a higher precedence, so add stubs with specific matchers last.

given(bird.canChirp(volume: any())).willReturn(true)     // Any volume
given(bird.canChirp(volume: notNil())).willReturn(true)  // Any non-nil volume
given(bird.canChirp(volume: 10)).willReturn(true)        // Volume = 10

Parameters

value Return​Type

A stubbed value to return.

Returns

The current stubbing manager which can be used to chain additional stubs.

will​Return(_:​transition:​)

@discardableResult
  public func willReturn(
    _ provider: ImplementationProvider<DeclarationType, InvocationType, ReturnType>,
    transition: TransitionStrategy = .onFirstNil
  ) -> Self  

Stub a mocked method or property with an implementation provider.

There are several preset implementation providers such as lastSetValue, which can be used with property getters to automatically save and return values.

given(bird.name).willReturn(lastSetValue(initial: ""))
print(bird.name)  // Prints ""
bird.name = "Ryan"
print(bird.name)  // Prints "Ryan"

Implementation providers usually return multiple values, so when using chained stubbing it's necessary to specify a transition strategy that defines when to go to the next stub.

given(bird.name)
  .willReturn(lastSetValue(initial: ""), transition: .after(2))
  .willReturn("Sterling")

print(bird.name)  // Prints ""
bird.name = "Ryan"
print(bird.name)  // Prints "Ryan"
print(bird.name)  // Prints "Sterling"

Parameters

provider Implementation​Provider<Declaration​Type, Invocation​Type, Return​Type>

An implementation provider that creates closure implementation stubs.

transition Transition​Strategy

When to use the next implementation provider in the list.

Returns

The current stubbing manager which can be used to chain additional stubs.

will(_:​)

@discardableResult
  public func will(_ implementation: InvocationType) -> Self  

Stub a mocked method or property with a closure implementation.

Use a closure to implement stubs that contain logic, interact with arguments, or throw errors.

given(bird.canChirp(volume: any()))
  .will { volume in
    return volume < 42
  }

Stubs are type safe and work with inout and closure parameter types.

protocol Bird {
  func send(_ message: inout String)
  func fly(callback: (Result) -> Void)
}

// Inout parameter type
var message = "Hello!"
given(bird.send(message: any())).will { message in
  message = message.uppercased()
}
bird.send(&message)
print(message)   // Prints "HELLO!"

// Closure parameter type
given(bird.fly(callback: any())).will { callback in
  callback(.success)
}
bird.fly(callback: { result in
  print(result)  // Prints Result.success
})

Parameters

implementation Invocation​Type

A closure implementation stub to evaluate.

Returns

The current stubbing manager which can be used to chain additional stubs.