I am aware of this example that shows how to create a mock chain extension and test that. However, I do not know how to test the chain extension that is used by the runtime and calling functions from pallets. How do I ensure the chain extension is interacting correctly with pallets?
I'm not sure if this is the simplest way, but I came up with a solution.
- Write a basic smart contract that calls each chain extension function
- Create a mock runtime using the chain extension
- Write a test that builds the contract, uploads it with
pallet_contracts::bare_instantiate. Then call the contract's functions and verify the state of the appropriate pallets.
There doesn't seem to be a clear way to test that e.g. a given
call function in a chain extension is set up to behave the way that is expected(because it's difficult to instantiate the
Environment struct externally).
Instead, you might break some parts out of
call and test them individually. For example, the matching on the
func_id is a large portion of the chain extension's work https://github.com/paritytech/ink/blob/6f105c2a0288b9a160385e1795375e5ad0350e34/examples/rand-extension/runtime/chain-extension-example.rs#L29-L48. You might split this out into a separate function that takes the function id and returns the expected call, if you can figure out a clean way to separate it from the
env.write(). Then, you can test this new function, for example.
You can also look at the existing ink! tests in the chain extension example that test chain extension setup more implicitly. In this case they are checking the state after using a chain extension that calls an extrinsic. https://github.com/paritytech/ink/blob/6f105c2a0288b9a160385e1795375e5ad0350e34/examples/rand-extension/lib.rs#L124-L155