Reactjs Jest/Enzyme等待元素具有特定属性

Reactjs Jest/Enzyme等待元素具有特定属性,reactjs,automated-tests,jestjs,enzyme,Reactjs,Automated Tests,Jestjs,Enzyme,我正在用React创建一个天气应用程序,并用酶对其进行测试,在每个页面上重新加载,在初始页面加载时,背景图像应该改变/加载 App.js 函数应用程序(){ const[背景,挫折]=使用状态(“”); 异步函数fetchBgImage(){ //getRandomImage返回从api获取的链接 挫折(等待getRandomImage()); } useffect(()=>{ fetchBgImage();//设置背景图像并将背景设置为图像url的方法 }, []); 返回( //这里back

我正在用React创建一个天气应用程序,并用酶对其进行测试,在每个页面上重新加载,在初始页面加载时,背景图像应该改变/加载

App.js

函数应用程序(){
const[背景,挫折]=使用状态(“”);
异步函数fetchBgImage(){
//getRandomImage返回从api获取的链接
挫折(等待getRandomImage());
}
useffect(()=>{
fetchBgImage();//设置背景图像并将背景设置为图像url的方法
}, []);
返回(
//这里backgound只是一个图像url
);
}
在现实世界中,应用程序运行良好,背景图像正确加载,并在每个页面上重新加载,但当我使用酶进行测试时,它不会等待backgound属性被设置,因此,src属性为空

App.test.js

beforeach(()=>{
//我读到useEffect不适用于浅层渲染
// https://github.com/airbnb/enzyme/issues/2086
spyOn(React,'useffect').mockImplementation((f)=>f());
});
它('显示背景图像',()=>{
常量包装器=浅();
const image=wrapper.find('#background_image');
//src道具为空
console.log(image.props());
});

那么如何让Ezyme等待设置图像的src属性呢?

您可以编写一个helper函数来等待属性。比如:

function waitForAttribute(el, attribute) {
    return new Promise((resolve, reject) => {
        const tryInterval = 100; // try every 100ms
        let maxTries = 10; //try 10 times
        let currentTry = 0;

        const timer = setInterval(() => {
          if (currentTry >= maxTries) {
            clearInterval(timer);
            return reject(new Error(`${attribute} not found on ${el.debug()}`));
          }

          const prop = el.props()[attribute]

          if (prop) {
            clearInterval(timer);
            resolve(el);
          }
          currentTry++

        }, tryInterval);
  });
}


it('displays background image', async () => {
  const wrapper = shallow(<App />);
  const image = wrapper.find('#background_image');
  const srcValue = await waitForAttribute(image, 'src')
  // ...do something with it
});
函数waitForAttribute(el,属性){
返回新承诺((解决、拒绝)=>{
const tryInterval=100;//每100毫秒重试一次
设maxTries=10;//尝试10次
设currentTry=0;
常量计时器=设置间隔(()=>{
如果(currentTry>=MaxTry){
清除间隔(计时器);
返回reject(在${el.debug()}`上找不到新错误(`attribute});
}
const prop=el.props()[属性]
如果(道具){
清除间隔(计时器);
解决(el);
}
当前尝试++
},tryInterval);
});
}
它('显示背景图像',异步()=>{
常量包装器=浅();
const image=wrapper.find('#background_image');
const srcValue=wait waitForAttribute(图像“src”)
//…用它做点什么
});

不清楚如何在测试代码中调用fetchBgImage(),iy也不清楚fetchBgImage是否承诺。。。所以问题可能是double@DmitryReutov是的,fetchBgImage返回了一个承诺,我编辑了我的答案以反映这一点,如果您希望看到数据中的更改,由异步代码触发,您应该使用wait,或者参数done。。。在这里你可以阅读
beforeEach(() => {
  // I read that useEffect doesnt work with shallow rendering 
  // https://github.com/airbnb/enzyme/issues/2086
  jest.spyOn(React, 'useEffect').mockImplementation((f) => f());
});

it('displays background image', () => {
  const wrapper = shallow(<App />);
  const image = wrapper.find('#background_image');
  // src prop is empty
  console.log(image.props());
});
function waitForAttribute(el, attribute) {
    return new Promise((resolve, reject) => {
        const tryInterval = 100; // try every 100ms
        let maxTries = 10; //try 10 times
        let currentTry = 0;

        const timer = setInterval(() => {
          if (currentTry >= maxTries) {
            clearInterval(timer);
            return reject(new Error(`${attribute} not found on ${el.debug()}`));
          }

          const prop = el.props()[attribute]

          if (prop) {
            clearInterval(timer);
            resolve(el);
          }
          currentTry++

        }, tryInterval);
  });
}


it('displays background image', async () => {
  const wrapper = shallow(<App />);
  const image = wrapper.find('#background_image');
  const srcValue = await waitForAttribute(image, 'src')
  // ...do something with it
});