0

我已经被这个问题困扰了将近 2 周。我正在尝试使用 react-query 创建一个 POC,以从外部源获取信息。此特定组件应调用 Service 方法并在结果表中列出结果。我在嘲笑这个方法来返回一些东西,但是测试失败了,因为它似乎是在调用端点来获取钱包之前执行的(此时,钱包是空的,所以什么都不会显示)。

这是我的测试:

describe('And there are wallets created', () => {
  test('Then it should render a list of wallets', async () => {
    const wallets: Wallet[] = [{id: 1, name: 'wallet 1'}, {id: 2, name: 'wallet 2'}];

    const listFn = jest.fn(() => {
      return Promise.resolve(wallets);
    });

    WalletService.list = listFn;

    renderComponent();
    
    screen.getByText("wallet 1"); //FAILS because no wallets are being rendered
  }); 
});

function renderComponent() {
  const queryClient = new QueryClient();

  render(
    <QueryClientProvider client={queryClient}>
      <ListWallet />
    </QueryClientProvider>
  );
}

这是我的组件:

const ListWallet: FC = () => {

  (...)
  const [wallets, setWallets] = useState<Wallet[] | null>(null);
  const { isLoading: isLoadingWallets, refetch: getAllWallets } = useQuery<Wallet[], Error>(
    "query-wallets",
    async () => {
      const wallets = await WalletService.list();
      return wallets;
    },
    {
      enabled: false,
      onSuccess: (res: Wallet[]) => {
        console.log('[onSuccess]: response is ' + JSON.stringify(res));
        setWallets(res);
      },
      onError: (err: any) => {
        (...)  
      },
    }
  );

  useEffect(() => {
    getAllWallets();
  });

  return (
    <div>
      <Card>
        <CardHeader title="wallets/list"/>
        <CardContent>
          <Grid container spacing={1}>
          <Table aria-label="simple table" data-testid="dataGrid">
            <TableHead>
              <TableRow>
                <TableCell>ID</TableCell>
                <TableCell>Wallet Name</TableCell>
                <TableCell></TableCell>
              </TableRow>
            </TableHead>

            <TableBody>
              {wallets !== null && wallets.map(wallet => (
                <TableRow key={wallet.id}>
                  <TableCell align="right">{wallet.id}</TableCell>
                  <TableCell align="right">{wallet.name}</TableCell>
                  <TableCell align="center">
                    <Button variant="text" 
                      color="secondary"
                      aria-label='Edit'
                      size='small'
                      data-testid="goToEditWallet">
                        edit
                    </Button>
                  </TableCell>
                </TableRow>
              ))}
              
            </TableBody>
          </Table>
          </Grid>
        </CardContent>
      </Card>
    </div>
  );
}

在控制台输出中,钱包显示为空,然后再次显示预期的信息,但视图中没有呈现任何内容。

控制台输出:

allWallets 为空
allWallets 为空
[onSuccess]:响应为 [{"id":1,"name":"wallet 1"},{"id":2,"name":"wallet 2"}]
[onSuccess] : 响应是 [{"id":1,"name":"wallet 1"},{"id":2,"name":"wallet 2"}]

我在这里做错了吗?我找到了带有测试的引用,但他们似乎将 useQuery 提取到自定义的钩子中,然后他们对其进行了模拟,但我想按照显示的方式使用它。如果没有办法让它通过,我将使用自定义钩子方法(它就是这样)。

4

1 回答 1

0

您需要等待异步操作结果。该测试不等待 UI 的更改。您应该使用waitForasync Query

await screen.findByText("wallet 1");

或者

await waitFor(() => screen.getByText("wallet 1"));

您可以使用它screen.debug()来检查expect在它之前可见的内容。

screen.debug()
screen.getByText("wallet 1");
于 2022-02-26T17:39:22.220 回答