Birdrides Mockingbird Versions Save

A Swifty mocking framework for Swift and Objective-C.

0.20.0

2 years ago

Targets

Framework

  • Xcode 12.5+ / Swift 5.4+
  • iOS 9.0+, macOS 10.10+, tvOS 9.0+, watchOS 7.4+

Generator

  • macOS 10.15+

Migrating from 0.19

Mocking static members no longer requires referencing the staticMock property when resetting mocks or clearing stubs/invocations.

// Old
reset(BirdMock.staticMock)
reset(type(of: mock(Bird.self)).staticMock)

// New
reset(BirdMock.self)
reset(type(of: mock(Bird.self)))  // Preferred equivalent

New Features

Test async methods

You can now mock, stub, and verify async methods. Note that stubbing and verifying declarations requires the use of the await keyword due to limitations with Swift’s overload resolution. Thanks to @ailtonvivaz for implementing this feature (#277).

protocol Bird {
  func fetchMessage() async -> String
}
let bird = mock(Bird.self)
given(await bird.fetchMessage()).willReturn("Hello")
print(await bird.fetchMessage())  // Prints "Hello"
verify(await bird.fetchMessage()).wasCalled()

Verify initializers

This release adds the ability to verify how mocks are initialized in cases where the metatype is provided to the system under test. Thanks to @myihsan for implementing this feature (#280).

protocol Bird {
  init(name: String)
}
func createBird(type: Bird.Type) -> Bird {
  return type.init(name: "Ryan")
}
let bird = createBird(type(of: mock(Bird.self)))
verify(bird.initialize(name: "Ryan")).wasCalled()

Enhancements

  • Improved the static mocking APIs and documentation (#287) @andrewchang-bird
  • Fixed handling of read-only subscripts (#285) @andrewchang-bird | @logicxd
  • Added the ability to mock sources in test bundles (#286) @andrewchang-bird | Karl
  • Fixed cache invalidation when generating mocks for targets outside of the test target’s project context (#278) @andrewchang-bird
  • Fixed handling of optional members in Objective-C protocols (#279) @andrewchang-bird

0.19.2

2 years ago

Patch Notes

  • Fixed pre-built library evolution and testability (#265) Andrew Chang | ugomarinelli
  • Fixed stubbing nested optional properties and Objective-C members (#274) Andrew Chang
  • Improved compile-time checks for stubbing Swift methods (#273) Andrew Chang
  • Removed Objective-C based nil check (#272) Andrew Chang | Ian Keen
  • Cleaned up Synchronized wrapper (#275) Andrew Chang

0.19.1

2 years ago

Patch Notes

  • Fixed package manager integrations and improved the example project tests (#263) Andrew Chang
  • Fixed configurator relative path handling when run outside of the test project source root (#264) Andrew Chang

0.19.0

2 years ago

Targets

Framework

  • Xcode 13.2 / Swift 5.5.2
  • iOS 9.0+, macOS 10.10+, tvOS 9.0+, watchOS 7.4+

Generator

  • macOS 10.15+

Migrating from 0.18

Re-configure SwiftPM projects

Mockingbird 0.19 improves support and guidance for setting up SwiftPM projects and packages. Previously, setting up a SwiftPM test target would use a path relative to $HOME for the generator executable, which wasn’t portable between development environments. If you use SwiftPM, you should consider re-configuring test targets with the new configure command to apply the fixes in 0.19.

Switch to the configure command

The install and download commands have been replaced with configure, which is a superset of the old commands but is not backwards compatible. Most workflows should be unaffected as these commands are only used to initially set up a project, not to generate mocks. See the Configure Command Options documentation for more information.

New Features

Configurator

Mockingbird now provides a streamlined configurator to improve the setup process for all package managers, especially SwiftPM. It supports referencing executables located in the project’s default derived data directory and advanced features like generating mocks for source targets located in another project with the --srcproject option. Supporting source files are also automatically downloaded and managed when running the configurator, making it even easier to set up projects for the first time.

$ mockingbird configure MockingbirdTests -- --targets MockingbirdTestsHost
🛠 Project: ~/mockingbird/Mockingbird.xcodeproj
🎯 Test Target: MockingbirdTests
🧰 Supporting sources: ~/mockingbird/MockingbirdSupport
✅ Downloaded supporting source files
✅ Added build phase 'Generate Mockingbird Mocks'
🎉 Successfully configured MockingbirdTests in 1s
🚀 Usage:
   1. Initialize a mock in your test with `mock(SomeType.self)`
   2. Build 'MockingbirdTests' (⇧⌘U) to generate mocks
   3. Write some Swifty tests!

Revamped Documentation

The README, wiki, and API reference are now unified and available at MockingbirdSwift.com which is powered by DocC, Apple’s fancy documentation compiler tool. The new site is better organized and prettier, but more importantly it’ll be much more searchable once Google finishes indexing it. The example projects have also been streamlined and include a new SwiftPM package example.

Enhancements

  • Fixed wildcard argument matching for Objective-C parameter types (#247) Andrew Chang | jdschin
  • Optimized dependency graph traversal for JSON project descriptions (#249) Andrew Chang | Jonathan Ueki
  • Fixed stubbing nil values on Objective-C mocks implicitly bridging to NSNull (#246) Andrew Chang | molenick-mov | Bohdan Orlov
  • Fixed nested optional codegen causing warnings about implicit type coercion to Any? (#248) Andrew Chang | Bohdan Orlov
  • Fixed cache invalidation when generating mocks for a source target in a different Xcode project (#250) Andrew Chang | Muzammil Mahmood
  • Fixed unavailable generic protocol mock initializer codegen (#251) Andrew Chang | Luke
  • Replaced SwiftPM argument parsing utils with Swift Argument Parser (#245) Andrew Chang
  • Added help message to file when no mockable types are generated (#252) Andrew Chang
  • Refactored build automation pipeline (#256) Andrew Chang

0.18.1

2 years ago

Patch Notes

0.18.0

2 years ago

Targets

  • Xcode 12.5 / Swift 5.4
  • iOS 9.0+, macOS 10.14+, tvOS 9.0+

New Features

Mocking Objective-C Types

This release introduces the ability to mock Objective-C classes and protocols using the same syntax as Swift types. Objective-C mocking is type-safe and requires no codegen. You can find more information in the library evolution RFC.

let peripheral = mock(CBPeripheral.self)
given(peripheral.name).willReturn("Bird")
print(peripheral.name)  // Prints "Bird"
verify(peripheral.name).wasCalled()

Partial Mocks (Spies)

You can create partial mocks in 0.18 that forward calls to a specific object or its underlying superclass (for Swift class mocks).

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

// Forward to an object
let bird = mock(Bird.self)
bird.forwardCalls(to: Crow(name: "Ryan"))
print(bird.name)  // Prints "Ryan"

// Forward to the superclass
let crow = mock(Crow.self).initialize(name: "Ryan")
crow.forwardCallsToSuper()
print(crow.name)  // Prints "Ryan"

It’s also possible to only forward specific invocations.

given(bird.name).willForward(to: Crow(name: "Ryan"))
given(crow.name).willForwardToSuper()

// Equivalent shorthand syntax
given(bird.name) ~> forward(to: Crow(name: "Ryan"))
given(crow.name) ~> forwardToSuper()

Property Accessor Syntax

It’s now possible to stub and verify properties through their normal getter and setter syntax instead of relying on the synthesized accessors.

// Old
given(bird.getName()).willReturn("Ryan")
given(bird.setName(any())).will { name in /* ... */ }

// New
given(bird.name).willReturn("Ryan")
given(bird.name = any()).will { name in /* ... */ }

Enhancements

0.17.0

2 years ago

Targets

  • Xcode 12.5 / Swift 5.4
  • iOS 8.0+, macOS 10.14+, tvOS 9.0+

Migrating from 0.16

Versioned CLI

Previously the recommendation for keeping the framework and generator versions synchronized was to use CocoaPods, write some boilerplate, or check it into the repo. As of 0.17, Mockingbird now ships with a launcher which is guaranteed to run the same generator version as the framework and can pull signed (or unsigned) binaries from arbitrary artifact providers (defaults to the release artifacts on GitHub). To migrate existing integrations, follow the set-up steps again or manually modify the “Generate Mockingbird Mocks” build phase to call the ./mockingbird launcher instead:

  • CocoaPods: Pods/MockingbirdFramework/mockingbird generate ...
  • Carthage: Carthage/Checkouts/mockingbird generate ...
  • Swift Package Manager:
DERIVED_DATA="$(echo "${OBJROOT}" | pcregrep -o1 '(/.*)/Build')"
REPO_PATH="${DERIVED_DATA}/SourcePackages/checkouts/mockingbird"
"${REPO_PATH}/mockingbird" generate ...

Thunk Pruning

The default pruning method is now omit instead of stub unreferenced mock types, which should result in improved source stability and fewer generated mocks. A side effect is that in order to get code completion for previously unreferenced types the test bundle needs to be built once to generate the definitions. For the previous behavior, pass stub to the generator --prune option.

Level Description
disable Always generate full thunks regardless of usage in tests.
stub Generate partial definitions filled with fatalError.
omit Don’t generate any definitions for unused types.

New Features

  • Added ability to specify asset bundle download URL (#201) ynx-zeissl
  • Added versioned CLI launcher (#202) Andrew Chang
  • Added support for imports gated by compilation directives (#205) Andrew Chang
  • Changed custom headers to fully replace the default header (#210) Andrew Chang
  • Added support for parsing project descriptions from Swift Package Manager (#215) Kiel Gillard

Enhancements

  • Fixed cache invalidation from multiple tests using the same lock file (#193) Péter Szabolcs Nagy
  • Fixed path processing bug for CI safe binaries run from a symlink (#196) Steven Hocking
  • Bumped Swift Syntax version to 5.4 for Xcode 12.5 (#204) Andrew Chang
  • Changed default thunk pruning level from 'stub' to 'omit' (#206) Andrew Chang
  • Removed incorrect mocking of methods in protocol extensions (#207) Andrew Chang
  • Improved parsing of function parameter attributes (#208) Andrew Chang
  • Updated Carthage integration tests to support Xcode 12 with XCFrameworks (#209) Andrew Chang

0.16.0

3 years ago

Targets

  • Xcode 12.0 / Swift 5.3
  • iOS 8.0+, macOS 10.14+, tvOS 9.0+

Migrating from 0.15

Thunk Pruning

The generator flag --disable-thunk-stubs has been replaced with the option --prune [disable|stub|omit]. Specify disable for the thunk pruning method to reproduce the previous flag behavior.

Level Description
disable Always generate full thunks regardless of usage in tests.
stub Generate partial definitions filled with fatalError.
omit Don’t generate any definitions for unused types.

New Features

  • Added the ability to pass ad hoc JSON project descriptions to the generator instead of a .xcodeproj file (#171) Andrew Chang
  • Added a thunk pruning option to fully exclude unused types from generating thunks (#174) Andrew Chang
  • Added support for setting GH_ACCESS_TOKEN to address rate limiting when downloading prebuilt binaries (#169) Andrew Chang

Enhancements

  • Improved support for Xcode 12 / Swift 5.3 and upgraded all dependency versions (#168) Andrew Chang
  • Improved handling of module names shadowed by top level nominal types (#172) Andrew Chang

0.15.0

3 years ago

Targets

  • Xcode 11.6 / Swift 5.2
  • iOS 8.0+, macOS 10.14+, tvOS 9.0+

Migrating from 0.14

Generic Mock Initialization

This release unifies the mock initialization API for generic types.

class MyClass {}
protocol MyProtocol {}

class MyGenericClass<T> {}
protocol MyGenericProtocol {
  associatedtype T
}

// Old
mock(MyClass.self)
mock(MyProtocol.self)

mock(MyGenericClassMock<Bool>.self)
mock(MyGenericProtocolMock<Bool>.self)

// New
mock(MyClass.self)     // no change
mock(MyProtocol.self)  // no change

mock(MyGenericClass<Bool>.self)
mock(MyGenericProtocol<Bool>.self)

Value Provider Semantics

Value provider has been simplified and no longer allows for hierarchical composition and decomposition.

// Old
var provider = ValueProvider()
provider.addSubprovider(.standardProvider)
provider.removeSubprovider(.standardProvider)

// New (mutating)
var provider = ValueProvider()
provider.add(.standardProvider)

// New (non-mutating)
let provider = ValueProvider() + .standardProvider
let provider = ValueProvider().adding(.standardProvider)

New Features

Enhancements

  • Updated code signing certificates and added CI action to build signed artifacts on commit with audit trail (#104) Andrew Chang | Ryan Meisters

0.14.1

3 years ago

Patch Notes

  • Fixed full thunks not being generated for generic types (#156) Andrew Chang | Jierong Li
  • Fixed full thunks not being generated for referenced types in newly added test files (#161) Andrew Chang | Alfredo
  • Fixed CocoaPods not including the downloaded prebuilt binary (#160) Andrew Chang | Luke | Ben Findeisen