I want to generate test mocks for protocols
Contributed by @marinbenc
For each protocol implementing AutoMockable
protocol or annotated with AutoMockable
annotation it will…
Create a class called ProtocolNameMock
in which it will…
For each function:
- Implement the function
- Add a
functionCalled
boolean to check if the function was called - Add a
functionReceivedArguments
tuple to check the arguments that were passed to the function - Add a
functionReturnValue
variable and return it when the function is called.
For each variable:
- Add a gettable and settable variable with the same name and type
Issues and limitations:
- Overloaded methods will produce compiler errors since the variables above the functions have the same name. Workaround: delete the variables on top of one of the functions, or rename them.
- Handling success/failure cases (for callbacks) is tricky to do automatically, so you have to do that yourself.
- This is not a full replacement for hand-written mocks, but it will get you 90% of the way there. Any more complex logic than changing return types, you will have to implement yourself. This only removes the most boring boilerplate you have to write.
Stencil template
Example output:
class MockableServiceMock: MockableService {
//MARK: - functionWithArguments
var functionWithArgumentsCalled = false
var functionWithArgumentsReceivedArguments: (firstArgument: String, onComplete: (String)-> Void)?
//MARK: - functionWithCallback
var functionWithCallbackCalled = false
var functionWithCallbackReceivedArguments: (firstArgument: String, onComplete: (String)-> Void)?
func functionWithCallback(_ firstArgument: String, onComplete: @escaping (String)-> Void) {
functionWithCallbackCalled = true
functionWithCallbackReceivedArguments = (firstArgument: firstArgument, onComplete: onComplete)
}
...