我正在使用Jest和Enzyme来测试React功能组件。
MyComponent:
export const getGroups = async () => {
const data = await fetch(groupApiUrl);
return await data.json()
};
export default function MyWidget({
groupId,
}) {
// Store group object in state
const [group, setGroup] = useState(null);
// Retrive groups on load
useEffect(() => {
if (groupId && group === null) {
const runEffect = async () => {
const { groups } = await getGroups();
const groupData = groups.find(
g => g.name === groupId || g.id === Number(groupId)
);
setGroup(groupData);
};
runEffect();
}
}, [group, groupId]);
const params =
group && `&id=${group.id}&name=${group.name}`;
const src = `https://mylink.com?${params ? params : ''}`;
return (
<iframe src={src}></iframe>
);
}
当我编写此测试时:
it('handles groupId and api call ', () => {
// the effect will get called
// the effect will call getGroups
// the iframe will contain group parameters for the given groupId
act(()=> {
const wrapper = shallow(<MyWidget surface={`${USAGE_SURFACES.metrics}`} groupId={1} />)
console.log(wrapper.find("iframe").prop('src'))
})
})
返回的src在url中不包含组信息。如何触发useEffect以及其中的所有内容?
useEffect已经被触发并且正在工作,关键是它的async
操作。因此,您需要等待提取完成。您可以执行的一种方法是:1.写下你的断言2.指定测试中的断言数,以使玩笑者知道它必须等待操作完成。
it('handles groupId and api call ', () => {
// the effect will get called
// the effect will call getGroups
// the iframe will contain group parameters for the given groupId
expect.assertions(1)
const wrapper = shallow(<UsageWidget surface={`${USAGE_SURFACES.metrics}`} groupId={2} />)
wrapper.update()
expect(whatever your expectation is)
});
因为在这个例子中我只是在断言上写的,
expect.assertions(1)
如果您写更多,则需要更改号码。
您可以设置超时以异步检查是否满足预期条件。
it('handles groupId and api call ', (done) => {
const wrapper = shallow(<UsageWidget surface={`${USAGE_SURFACES.metrics}`} groupId={1} />)
setTimeout(() => {
expect(wrapper.find("iframe").prop('src')).toBeTruthy(); // or whatever
done();
}, 5000);
}
超时允许您等待异步提取完成。最后调用done()
表示it()
块已完成。
您可能还想对mock implementation函数进行getGroups
处理,以使您每次测试代码时都不会真正碰到网络API。