Instantiating models for tests is not a simple task. Sometimes, the initializer has too many attributes and the test does not rely on the full set of attributes. This inconvenience hurts our ability to efficiently unit test our app, which could discourage members from writing them at all.
To help with this, we have introduced a module called Fakes at Modules/Sources/Fakes. This module defines .fake() functions for all of our networking models.
The .fake() function instantiates a type with fake values. As of now, we are defining fake values as empty values.
This, in conjunction with the copiable pattern allow us to write tests like:
func test() {
// Given
let initialProduct = Product.fake()
let expectedProduct = initialProduct.copy(name: "new-name")
let ViewModel = ViewModel(product: initialProduct)
// When
viewModel.updateName("new_name")
// Then
XCTAssertEqual(viewModel.product, expectedProduct)
}Note: This module is meant to be used in test targets only!
The fake() methods are generated using Sourcery. For now, only classes, structs, and enums of the Networking, Yosemite, and Hardware targets are supported.
To generate a fake() method:
-
Make it conform to
GeneratedFakeable.import Codegen struct ProductSettings: GeneratedFakeable { ... }
Note: for enum types, if an enum only conforms to
GeneratedFakeableitsfake()method won't be generated. As a workaround, the enum can conform to basic protocols likeEquatable. -
In the terminal, navigate to the project's root folder and run
rake generate.$ cd /path/to/root $ rake generateThis will update the Fakes.generated file with the new
fake()method. -
Compile the project.
The rake generate command executes the Sourcery configuration files located in the CodeGeneration/Sourcery/Fakes folder.
Networking module → Networking-Fakes.yaml
Yosemite module → Yosemite-Fakes.yaml
Hardware module → Hardware-Fakes.yaml
It uses a single template, Fakes.swifttemplate, to generate the code. It's written using Swift templates.
Please refer to the Sourcery reference for more info about how to write templates.
- Add
Codegento thedependenciesin the module target definition inModules/Package.swift - Add a new file
{{ModuleName}}-Fakes.yamlunderCodeGeneration/Sourcery/Fakessimilar to other yaml files in the same folder. - In
Fakes.swifttemplate, add a line to import the new framework. - In
Rakefilewhich includes the script forrake generatecommand, add the new framework to the list of frameworks forFakeablegeneration similar to other frameworks. - Now you can try generating fake methods as instructed in an earlier section.