When you execute any tests, you need to make some `test doubles`.
This is a tip as to implement `Stub`.
Typically, a stub is an object that returns a fixed output. So, It can be implemented like the following.
final class StubDependencyGenerator: DependencyGenerating {
func generate(option1: Bool, option2: Bool, option3: Bool) -> Dependency {
Dependency(name: "Stub\(option1)\(option2)\(option3)")
}
}
The Stub object in above is always returns fixed output.
Moreover, you can add the `name` property into the stub to make a better.
final class StubDependencyGenerator: DependencyGenerating {
var name: String = ""
func generate(option1: Bool, option2: Bool, option3: Bool) -> Dependency {
Dependency(name: "\(name)\(option1)\(option2)\(option3)")
}
}
However, the way using parameters is still even inflexible a little. It means, the way of generating a `Dependency` is always fixed regardless of variable; The options as parameters are always appended to name, no matter what the value of the variable is.
If you want to flexible control the `generate` method, you can use a closure for generating a `Dependency`.
final class BetterStubDependencyGenerator: DependencyGenerating {
var generateStub: ((Bool, Bool, Bool) -> Dependency)?
func generate(option1: Bool, option2: Bool, option3: Bool) -> Dependency {
return generateStub?(option1, option2, option3) ?? Dependency(name: "")
}
}
I first saw the code similary on the test case in `tuist`.
If you add the closure like above `generateStub`, you can control the way to generate a `Dependency` as you want.
func test_generate() {
// Given
aDependencyGenerator.generateStub = { option1, _, _ -> Dependency in
if option1 {
return Dependency(name: "Option1Stub1") // It used
} else {
return Dependency(name: "Stub1")
}
}
bDependencyGenerator.generateStub = { _, _, _ -> Dependency in
return Dependency(name: "JustStub2")
}
// When
let product = subject.generate()
// Then
XCTAssertEqual(product.name, "Option1Stub1.JustStub2.")
}
It makes more isolated and flexible testing. 👍