(Apollo client v3)useLazyQuery自定义钩子测试

(Apollo client v3) useLazyQuery custom hook testing

我一直在努力解决自定义 useLazyQuery 挂钩的测试问题。我的第一个测试通过了,但第二个测试失败了。第二次测试有什么问题?

这是useLazyFetchCoin.tsx

export const useLazyFetchCoin = () => {
  const [coins, setCoins] = useState<ICoin[]>([]);

  useEffect(() => {
    const coins = localStorage.getItem('coinsInfo');
    if (coins) {
      setCoins(JSON.parse(coins));
    }
  }, []);

  const [getData, { loading, error }] = useLazyQuery(GET_COIN_PRICE_QUERY, {
    fetchPolicy: 'network-only',
    notifyOnNetworkStatusChange: true,
    onCompleted: (data) => {
      const hasSameCoin = coins.some((f) => f.id === data.markets[0]?.id);
      if (data.markets.length && !hasSameCoin) {
        const allCoins = [...coins, data.markets[0]];
        setCoins(allCoins);
        localStorage.setItem('coinsInfo', JSON.stringify(allCoins));
      } else if (data.markets.length <= 0) {
        alertNotification('Coin not found !', Notification.ERROR);
      }
      if (hasSameCoin) {
        alertNotification('This coin already exists on your list !', Notification.WARNING);
      }
    }
  });

  return { coins, setCoins, getData, loading, error };
};

这是测试文件

describe('useLazyFetchCoin custom hook', () => {
  const QueryMock = [
    {
      request: {
        query: GET_COIN_PRICE_QUERY,
        variables: { code: 'BNB' }
      },
      result: {
        data: {
          markets: [
            {
              id: 'binance_bnb_eur',
              baseSymbol: 'BNB',
              ticker: {
                lastPrice: '414.90000000'
              }
            }
          ]
        }
      }
    }
  ];

  const QueryWrongCodeMock = [
    {
      request: {
        query: GET_COIN_PRICE_QUERY,
        variables: { code: 'asd' }
      },
      result: {
        data: {
          markets: []
        }
      }
    }
  ];

  function getHookWrapper(mocks: any, code: string) {
    const wrapper = ({ children }: any) => (
      <MockedProvider mocks={mocks} addTypename={false}>
        {children}
      </MockedProvider>
    );
    const { result, waitForNextUpdate } = renderHook(() => useLazyFetchCoin(), {
      wrapper
    });

    expect(typeof result.current.coins).toBe('object');
    expect(result.current.loading).toBeFalsy();
    expect(result.current.error).toBeUndefined();

    // call the lazy function
    act(() => {
      result.current.getData({
        variables: { code }
      });
    });

    return { result, waitForNextUpdate };
  }

  it('should return an array of coins', async () => {
    // Working correctly
    const { result, waitForNextUpdate } = getHookWrapper(QueryMock, 'BNB');

    await waitForNextUpdate();

    expect(result.current.loading).toBeFalsy();
    expect(result.current.coins[0]).toEqual({
      id: 'binance_bnb_eur',
      baseSymbol: 'BNB',
      ticker: {
        lastPrice: '414.90000000'
      }
    });
  });

  it('should return an empty array when requesting a wrong code', async () => {
    // Not working
    const { result, waitForNextUpdate } = getHookWrapper(QueryWrongCodeMock, 'asd');

    await waitForNextUpdate();

    expect(result.current.loading).toBeFalsy();
    expect(result.current.coins[0]).toEqual([]);
  });
});

我在第二次测试时收到此错误消息。

Expected: []
Received: {"baseSymbol": "BNB", "id": "binance_bnb_eur", "ticker": {"lastPrice": "414.90000000"}}

我不明白,因为我对每个测试使用不同的查询。

此外,当您传递错误代码(例如 'asd'.

时,第二个测试应该会收到一个空数组

如何为它编写适当的测试?

我解决了这个问题。当我在更改订单测试时,它工作正常。

我为它添加了一个明确的模拟函数。

clear mock