- Notifications
You must be signed in to change notification settings - Fork128
Framework for automatic mock generation. Adds a set of handy methods, simplifying testing. One of the best and most complete solutions, including generics support and much more.
License
MakeAWishFoundation/SwiftyMocky
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Check outguides, or fulldocumentation
SwiftyMocky is a strongly typed framework for Mockito-like unit testing experience. Library depends onSourcery, that scans your source code andgenerates Mocks Swift code for you!
The idea ofSwiftyMocky is to automatically mock Swift protocols and protocol compositions. The main features are:
- easy syntax, utilising full power of auto-complete, which makes writing test easier and faster
- we DO support generics
- mock implementations generation
- a way to specify what mock will return (given)
- possibility to specify different return values for different attributes
- record stubbed return values sequence
- verify, whether a method was called on mock or not
- check method invocations with specified attributes
- it works with real device
CLI was moved bask to the main (this) repo. CLI in thisrepository will be supported at least until version 5.0.0.
Current version has several significant changes. It removes deprecated methods (which might be breaking) and deprecates having CLI in the newrepository.
SwiftyPrototype was also extracted to separate library. There are no more compilation flags, so if you were relying onSwiftyMocky with-DMockyCustom, you will have to switch toSwiftyPrototype.
We consider current version as stable. We are moving toward using the newMockfile but the previous configuration format would be still supported. Library works with Swift4.1, 4.2, 5.0, 5.1.2 and Sourcery 1.0.x.
While it is technically possible to integrate SwiftyMocky on Linux targets, there is no Mock generation feature there yet. You can use SwiftyMokcy runtime via SwiftPM though, as long as your are fine with generating mocks on mac machine.
The migration is not required, you can keep usingSwiftyMocky as you did before. TheLegacy setup is described inguides section.
Still, we would encourage to try newCLI and share a feedback. We believe it will make using and setting upSwiftyMocky way easier. If you have an existing setup, install CLI as per thisguide and try:
> swiftymocky migrateSwiftyMocky is available throughCocoaPods. To install it, simply add the following line to your Podfile:
pod"SwiftyMocky"
Use CLI tool from your project directory:
# To setup initial Mockfile% ./Pods/SwiftyMocky/bin/swiftymocky setup# To generate mocks% ./Pods/SwiftyMocky/bin/swiftymocky generate
To install, add following to you Cartfile:
github"MakeAWishFoundation/SwiftyMocky"
Then executecarthage update
ForCarthage, few additional steps are required
You need to install CLI to generate mocks - seeinstallation
AddSwiftyMocky to youPackage.swift dependencies:
dependencies:[.package(url:"https://github.com/MakeAWishFoundation/SwiftyMocky", from:"4.2.0"),]
You need to install CLI to generate mocks - seeinstallation
Note: Examples ofSwiftyMocky integration as a tool for Unit tests, as well as a Prototyping framework, are here:https://github.com/MakeAWishFoundation/SM-Integration-Tests
> brew install mint> mint install MakeAWishFoundation/SwiftyMocky
> marathon install MakeAWishFoundation/SwiftyMockyMake:
Clone fromhttps://github.com/MakeAWishFoundation/SwiftyMockyCLI and runmake in the root directory.
Annotate your protocols that are going to be mocked, making them adoptAutoMockable protocol, or adding annotation comment above their definition in the source code.
Mocks are generated from your project root directory, based on configuration insideMockfile.
> path/to/swiftymocky setup# if you don't have a Mockfile yet> path/to/swiftymocky doctor# validate your setup> path/to/swiftymocky generate# generate mocks
More informations aboutCLI andmock generation
If you don't want to migrate to ourCLI and prefer to use "raw" Sourcery, please referto this section in documentation.
Create 'dummy' protocol somewhere in your project, like:protocol AutoMockable { }
Adopt it by every protocol you want to actually mock.
protocolToBeMocked:AutoMockable{ // ...}
Alternatively, mark protocols that are meant to be mocked with sourcery annotation as following:
//sourcery: AutoMockableprotocolToBeMocked{ // ...}
Or use it to protocol compositions:
typealiasToBeMocked=OneProtocol&TwoProtocols&AutoMockable
Every protocol in source directories, having this annotation, will be added toMock.generated.swift
All mocks hasgiven method (accessible both as instance method or global function), with easy to use syntax, allowing to specify what should be return values for given methods (based on specified attributes).
All protocol methods are nicely put intoGiven, with matching signature. That allows to use auto-complete (just type.) to see all mocked protocol methods, and specify return value for them.
All method attributes are wrapped asParameter enum, allowing to choose betweenany andvalue, giving great flexibility to mock behaviour. Please consider following:
Given(mock,.surname(for name:.value("Johnny"), willReturn:"Bravo"))Given(mock,.surname(for name:.any, willReturn:"Kowalsky"))print(mock.surname(for:"Johny")) // Bravoprint(mock.surname(for:"Mathew")) // Kowalskyprint(mock.surname(for:"Joanna")) // Kowalsky
In verions 3.0 we introduced sequences and policies for better control of mock behvaiour.
Given(mock,.surname(for name:.any, willReturn:"Bravo","Kowalsky","Nguyen"))print(mock.surname(for:"Johny")) // Bravoprint(mock.surname(for:"Johny")) // Kowalskyprint(mock.surname(for:"Johny")) // Nguyenprint(mock.surname(for:"Johny")) // and again Bravo// ...
For more details please see fulldocumentation.
All mocks hasverify method (accessible both as instance method or global function), with easy to use syntax, allowing to verify, whether a method was called on mock, and how many times. It also provides convenient way to specify, whether method attributes matters (and which ones).
All protocol methods are nicely put intoVerify, with matching signature. That allows to use auto-complete (just type.) to see all mocked protocol methods, and specify which one we want to verify.
All method attributes are wrapped asParameter enum, allowing to choose betweenany,value andmatching, giving great flexibility to tests. Please consider following:
// inject mock to sut. Every time sut saves user data, it should trigger storage storeUser methodsut.usersStorage= mockStoragesut.saveUser(name:"Johny", surname:"Bravo")sut.saveUser(name:"Johny", surname:"Cage")sut.saveUser(name:"Jon", surname:"Snow")// check if Jon Snow was stored at least one timeVerify(mockStorage,.storeUser(name:.value("Jon"), surname:.value("Snow")))// storeUser method should be triggered 3 times in total, regardless of attributes valuesVerify(mockStorage,3,.storeUser(name:.any, surname:.any))// storeUser method should be triggered 2 times with name JohnyVerify(mockStorage,2,.storeUser(name:.value("Johny"), surname:.any))// storeUser method should be triggered at least 2 times with name longer than 3Verify(mockStorage,.moreOrEqual(to:2),.storeUser(name:.matching({ $0.count>3}), surname:.any))
ForVerify, you can useCount to specify how many times you expect something to be triggered.Count can be defined as explicit value, like1,2,... or in more descriptive and flexible way, like.never,more(than: 1), etc.
From SwiftyMocky 3.0, it is possible to useGiven and performVerify on properties as well, with respect to whether it is get or set:
mock.name="Danny"mock.name="Joanna"print(mock.name)// Verify getter:Verify(mock,1,.name)// Verify setter:Verify(mock,2,.name(set:.any))Verify(mock,1,.name(set:.value("Danny")))Verify(mock,.never,.name(set:.value("Bishop")))
All mocks hasperform method (accessible both as instance method or global function), with easy to use syntax, allowing to specify closure, that will be executed upon stubbed method being called.
It uses same parameter wrapping features as given, so you can specify differentPerform cases for different attributes set.
It's very handy when working with completion block based approach.
Example:
// Perform allows to execute given closure, with all the method parameters, as soon as it is being calledPerform(mock,.methodThatTakesCompletionBlock(completion:.any, perform:{ completionincompletion(true,nil)}))
Full documentation is availablehere, as well as throughdocs directory.
Guides -Table of contents
Changelog is availablehere
For list all supported features, check documentationhere orguides
For more examples, check out our example project, or examples section inguides.
To run the example project, clone the repo, and runpod install from the Example directory first.
To trigger mocks generation, runrake mock orswiftymocky generate from root directory (if you installed CLI).
- stubbing protocols in elegant way
- template for generating mocks
- example project
- stubbing protocols with variables
- method signature generation without name conflicts
- cover 95% of framework codebase with unit tests
- cover 95% of framework codebase with documentation
- add unit tests for template
- support for tvOS, Linux and MacOS
- Carthage support
- Subscripts support
- Stub return values as sequences
- Simple tool simplifying configuration process
- Przemysław Wośko,wosko.przemyslaw@gmail.com
- Andrzej Michnia,amichnia@gmail.com
SwiftyMocky is available under the MIT license. See theLICENSE file for more info.
About
Framework for automatic mock generation. Adds a set of handy methods, simplifying testing. One of the best and most complete solutions, including generics support and much more.
Topics
Resources
License
Code of conduct
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.

