我使用Jest和@testing-library/react,同时使用来自@apollo/client/testing的MockedProvider模拟数据。在试图弄清楚如何更改单击时发生的变化时,我在这个测试中发现了这个非常奇怪的行为:
test('Test 1', async () => {
mockAllIsIntersecting(true);
renderTest(() => (
<MockedApolloProvider
mocks={[
getProductMock({ code: '7340266_F671' }),
appSettingsSalesDocumentMock(),
]}
>
<ProductCard
product={productMock}
language="no"
translated={translatedMock}
/>
</MockedApolloProvider>
));
fireEvent.click(await screen.findByTitle('A'));
const img = screen.getByAltText(
'B',
);
console.log(img);
expect(img.getAttribute('src')).toEqual(
'C',
);
});
1.首先,单击事件假定更改图像(到图像2)
1.通过搜索“A”找到更改图像的链接(带有preventDefault的a-href标记)
1.然后我在上面做一个fireEvent.click
1.它应该从MockedApolloProvider获取模拟数据
1.图像1现在应该已经改变了源代码,但是当我试图在控制台中找到图像2时,图像仍然是旧的图像1。
但奇怪的是,如果我改变getByAltText('B'),其中B是DOM中没有的其他东西,测试打印出它不匹配,以及可用的DOM看起来像什么,现在突然变成了正确的Image(图2)。
它看起来像当screen.getByAltText('B')被成功地找到,点击事件得到恢复???
下面是正在使用的组件的Veery简化版本,试图包括重要/相关的部分:
export const ProductCard: React.FC<ProductCardProps> = memo(
({ product }) => {
const [productState, setProductState] = useState(product);
const currProduct = productState;
const { code, url, siblings } = currProduct;
const loadProduct = (productCode: string) => {
getProduct({
variables: { variantCode: productCode },
onCompleted: (data) => {
data.getProduct && setProductState(data.getProduct);
},
});
};
const onSiblingClick = (
productCode: string,
event: React.MouseEvent<HTMLElement>,
) => {
event.preventDefault();
if (currProduct.code === productCode) {
return false;
}
loadProduct(productCode);
};
return (
<ProductCardContainer>
<ProductCardImageContainer>
<ProductCardHoverElements
currProduct={currProduct}
product={product}
/>
</ProductCardImageContainer>
{/* onSiblingClick gets triggered in the test*/}
<ProductColors
code={code}
productUrl={url}
siblings={siblings}
onSiblingClick={onSiblingClick}
numberOfVisibleSwatches={3}
size="small"
ariaLabelMoreColors="More colors"
/>
</ProductCardContainer>
);
},
(prevProps, nextProps) => {
return prevProps.product.code === nextProps.product.code;
},
);
注意:图像1和图像2都有相同的“B”替换文本
注2:screen.findByTitle('A')是一个在组件中带有clickHandler的超链接(a-href)
1条答案
按热度按时间7cjasjjr1#
不应该在act中 Package fireEvent的原因是它是多余的,因为fireEvent已经 Package 在act中了。然而,这里有一个重要的区别。你不仅仅是在act中 Package fireEvent,而是在异步行为中 Package 它并等待它:
这与fireEvent Package 在其中的正常行为不同,不应该从esLint收到投诉。您可以在类型定义中看到不同的类型:
除了在async act中 Package fireEvent之外,你还可以经常使用waitFor来处理它后面的expect。我现在稍微喜欢这个。