The test framework includes extensive mocks for unit tests, which are effectively indispensable.
### Why
Unit tests rely on mocks to isolate tests from external dependencies. The `vault` object is crucial in all contracts and mocking its methods and attributes accurately is therefore key to getting representative tests. However, it is not obvious how certain aspects should be mocked accurately without reverse engineering behaviour from simulator and/or end-to-end tests. This is compounded by the fact that the many `vault` methods and attribute behaviours are often derived from similar data (e.g. postings data will impact `vault.get_postings()` and `vault.get_client_transactions()`). Mocking these independently further adds to the risk that the mocks are not accurate and the tests do not actually provide good coverage.
To reduce this risk, we have developed mocks and associated helpers to get accurate tests and also reduce the burden on test writers/readers. We typically expose them via the `ContractTest` and `SupervisorContractTest` `TestCase` classes.
### How
The `create_mock()` methods on `ContractTest` and `SupervisorContractTest` let test writers pass in data and create a mock `vault` object for use in tests. In some cases, the input data is fairly self-explanatory, but the next sections clarify some of the more complicated areas.
Be careful to not mix up data relevant to the hook's data requirements (i.e. what is controlled by `@requires` decorators) and the inputs to the hook themselves. For example, the `postings` argument is a `PostingInstructionBatch` input available to `pre_posting_code` and `post_posting_code`. Conversely, the `vault.get_postings()` method can return additional historic postings, depending on the `@requires` specifics.
#### Parameters
Many tests revolve around different parameter values and how these affect contract execution outputs. As each contract can use different parameters, it makes sense to manage these at a contract level. To this end we recommend extending `ContractTest`'s `create_mock()` method to handle parameter inputs. `ContractTest` has a `locals_to_ignore` attribute that allows writers to easily filter out locals that won't be relevant and consider the rest as parameters. For example: