# Unit Testing

### Testing

To test cross-chain contracts, we leverage mocking patterns. [`MockTelepathy`](https://github.com/succinctlabs/telepathy-contracts/blob/main/src/amb/mocks/MockTelepathy.sol) simulates the behavior of `TelepathyRouter` without the overhead of generating and relaying proofs. An example is below.

```solidity
pragma solidity 0.8.16;

import "forge-std/console.sol";
import "ds-test/test.sol";
import "forge-std/Vm.sol";
import "forge-std/Test.sol";

import "src/amb/mocks/MockTelepathy.sol";

import "./ExampleCounter.sol";

contract CounterTest is Test {
    uint32 constant SOURCE_CHAIN = 1;
    uint32 constant TARGET_CHAIN = 100;

    MockTelepathy router;
    MockTelepathy receiver;
    SourceCounter source;
    TargetCounter target;

    function setUp() public {
        router = new MockTelepathy(SOURCE_CHAIN);
        receiver = new MockTelepathy(TARGET_CHAIN);
        router.addTelepathyReceiver(TARGET_CHAIN, receiver);

        source = new SourceCounter(address(router), TARGET_CHAIN);
        target = new TargetCounter(address(receiver));
    }

    function test_IncrementOne() public {
        source.increment(1, address(target));
        router.executeNextMessage();
        require(target.counter() == 1);
    }

    function test_IncrementSeveral() public {
        source.increment(2, address(target));
        router.executeNextMessage();
        require(target.counter() == 2);
        source.increment(123456789, address(target));
        router.executeNextMessage();
        require(target.counter() == 123456791);
    }

    function test_IncrementOverflow() public {
        source.increment(
            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, address(target)
        );
        router.executeNextMessage();
        require(
            target.counter() == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
        );
        source.increment(2, address(target));
        router.executeNextMessage();
        require(target.counter() == 1);
    }
}
```

We specify our `router` and `receiver` to be `MockTelepathy` contracts that simulate the behavior of `TelepathyRouter` on the source and destination chain, respectively. We then specify our counter contracts on the source and contract chains with `source` and `target`.

To test `source` and `target`, we use `source.increment()...` to increment. Then, we *must* call `router.executeNextMessage()` to make our `MockTelepathy` routers relay the call to `target`. In doing so, we implicitly call `target.handleTelepathyImpl(...)`! Without calls to `router.executeNextMessage()`, our messages would be in a queue on the mock source chain, waiting to be relayed to the specified destination chain.

## MockTelepathy Methods

These are methods unique to [`MockTelepathy`](https://github.com/succinctlabs/telepathy-contracts/blob/main/src/amb/mocks/MockTelepathy.sol) that don't exist in `TelepathyRouter`.

* `addTelepathyReceiver(uint32 _chainId, MockTelepathy _receiver)`: This method tells a source chain router which `MockTelepathy` instance to route messages to that are sent to `_chainId`.
* `executeNextMessage()`: Broadcast next message in queue to receiver `MockTelepathy` instance

`MockTelepathy` can be used with `forge` testing. Examples can be found below:

* [Counter tests](https://github.com/succinctlabs/telepathy-contracts/blob/main/examples/example-counter/ExampleCounter.t.sol)
* [Bridge tests](https://github.com/succinctlabs/telepathy-contracts/blob/main/examples/bridge/Bridge.t.sol)
* [Uniswap example tests](https://github.com/succinctlabs/telepathy-contracts/blob/main/examples/uniswap/UniswapExample.t.sol)
