正在测试加载页面时执行的useQuery挂钩



我已经被这个问题困扰了将近两个星期。我正在尝试创建一个带有react查询的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>
);
}

在控制台输出中,钱包显示为null,然后再次显示它和期望的信息,但视图中没有任何内容。

控制台输出:

allWallets为空
allWallets无效
[onSuccess]:响应为[{"id"1,"name"wallet 1",{quot;id":2"、"名称":"钱包2"}]

我是不是做错了什么?我在测试中找到了引用,但他们似乎将useQuery提取到了一个定制的钩子中,然后他们对它进行了模拟,但我希望按照显示的方式使用它。如果没有办法让它通过,我将使用自定义钩子方法(好吧,它就是这样(。

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

await screen.findByText("wallet 1");

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

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

screen.debug()
screen.getByText("wallet 1");

最新更新