fuels-ts icon indicating copy to clipboard operation
fuels-ts copied to clipboard

Add `setupTestProvider` test utility

Open nedsalk opened this issue 2 years ago • 2 comments

Motivation

Tests in the providers package related to actually connecting to a node fall into two categories:

  1. Those that mock the call (e.g. provider.test.ts -> it('can getMessageProof with all data')),
  2. Those that assume a node is already running (e.g. provider.test.ts -> it('can getBlocks')).

Those that mock the call assume a certain response from the node (an assumption that could change from version to version), whereas those that assume a node is running will fail when run in isolation if the node is not running.

We should have a setupTestProvider utility (akin to the rust-sdk's) which can start a node and then return a Provider instance. We can use launchNode.ts, but we'd have to move this utility to e.g. packages/utils or packages/providers. We can also rewrite launchNodeAndGetWallets to internally use setupTestProvider, given that packages/wallet depends on packages/providers.

This would also be a step forward in the right direction to close #296, as each test would be running its own node, so they would be completely isolated from each other and no UTXO issues would pop up.

Usage example

// setupTestProvider.ts

export async function setupTestProvider(options?: ProviderOptions): Promise<Provider> {
const { ip, port } = await launchNode(...);

return new Provider(`http://${ip}:${port}/graphql`);
}

// provider.test.ts
it('can getBlocks', async () => {
    const provider = await setupTestProvider();
    await provider.produceBlocks(10);
    const blocks = await provider.getBlocks({
      last: 10,
    });
    ...
});

 it('can cacheUtxo [numerical]', async () => {
    using provider = await setupTestProvider({
      cacheUtxo: 2500,
    });
    expect(provider.cache).toBeTruthy();
    expect(provider.cache?.ttl).toEqual(2_500);
});

Possible implementations

The problem with running a node per test is how to kill a node after the test is finished? This can probably be solved by using the TS 5.2 using declaration. We can close the node via [Symbol.asyncDispose]. We can add this property to the Provider instance returned by setupTestProvider.

The good thing is that launchNode.ts already has everything necessary for starting and closing a node, so this would just build upon that.

nedsalk avatar Sep 14 '23 10:09 nedsalk

Thoughts on the addition of a method for creating a local / in-memory node which also allows us to configure wallets similar to how the Rust SDK does it?

Braqzen avatar Sep 29 '23 20:09 Braqzen

@Braqzen Thanks for the idea, it led me to #1356 which introduces everything you requested.

nedsalk avatar Nov 14 '23 15:11 nedsalk