# Testing w/ Mocks

For unit testing within Foundry, we rely on Mocks.sol to simulate calls to other contracts (e.g. Ladle, Cauldron) as well as their return values.&#x20;

Mocks.sol is a library and has to be attached to each abstract contract - not just the first, StateZero.

#### **Usage in test contract:**

```solidity
import "./utils/Mocks.sol" 

abstract contract WitchV2StateZero is Test, TestConstants { 
    using Mocks for *;
...
}
```

## **Mocks.sol**

* collection of function signatures&#x20;
* relies on function overloading for ease of use -> can simply call mock on an external method to be simulated.

### mock() functions:

* based on vm.mockCall()
* Mocks a call to an address, returning specified calldata.

![mockCall](https://1628544884-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTgomzlmn9NrxUY0OQ3cD%2Fuploads%2FSFoOE9R4LUwDvetuj9RN%2Fimage.png?alt=media\&token=6f0d0583-bcd1-4460-a306-8b8ffa8659a8)

#### Example:

```solidity
// In ContangoLadle.t.sol:
address bob = address(0xb0b);

DataTypes.Vault memory vault = DataTypes.Vault({
            owner: bob,
            seriesId: "series",
            ilkId: "ilk"
        });

cauldron.build.mock(bob, "vaultId", "series", "ilk", vault); 
cauldron.build.verify(bob, "vaultId", "series", "ilk");


// in Cauldron.sol: 
function build(address owner, bytes12 vaultId, bytes6 seriesId, bytes6 ilkId)
```

* mock `build` function in cauldron&#x20;
* since mock is a library fn, it takes the function `build` as its first parameter:

![matching mock fn signature](https://1628544884-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTgomzlmn9NrxUY0OQ3cD%2Fuploads%2FxNbTI35h1r4C7BNvcK5z%2Fimage.png?alt=media\&token=adbc65de-cf7f-4e28-9e09-612705380098)

* `mockCall` takes 3 parameters:

  * address of bob -> f.address&#x20;
  * input calldata -> abi.encodeWithSelector(f.selector, p1, p2, p3, p4)
  * returns calldata -> abi.encode(r1)

**We need to specify the data that is returned. In this case, we expect the struct vault to be the returns calldata.**

* hence `vault` as specified when calling mock

## Mocking a contract

![](https://1628544884-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTgomzlmn9NrxUY0OQ3cD%2Fuploads%2FgGl7z4WyzZpqZcpKDEAb%2Fimage.png?alt=media\&token=f96be3fe-76af-4341-9330-49c164543e5b)

**Mocks.mock("Cauldron") matchs the fn signature:**

![Mock.sol](https://1628544884-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTgomzlmn9NrxUY0OQ3cD%2Fuploads%2FCQCtWIx5oOWHh3WmMzUH%2Fimage.png?alt=media\&token=debf15ac-d6a7-4614-8e41-2e6833318a68)

* StrickMock()

![](https://1628544884-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTgomzlmn9NrxUY0OQ3cD%2Fuploads%2FAM3Hrqiok5u8ik6bki3E%2Fimage.png?alt=media\&token=b8c34320-94a7-4b0a-8d6e-5e8be603315d)

* a placeholder contract is deployed at an address and labelled as "Cauldron".
* the deployed address is returned, which is subsequently passed into the interface ICauldron.

## verify() functions:

* based on `expectCall()` from Vm.sol

![](https://1628544884-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTgomzlmn9NrxUY0OQ3cD%2Fuploads%2FGI066PK5Iq3qEeLlkE0X%2Fimage.png?alt=media\&token=2f412e39-d341-4a13-adbd-73258d71df14)

* test in general a particular path was hit in a smart contract that calls another contract
