开玩笑/酶等待元素具有特定的属性

时间:2019-12-25 15:11:51

标签: reactjs automated-tests jestjs enzyme

我正在用React创建一个天气应用,并用酶对其进行测试,在每次重新加载页面和初始页面加载时,背景图像都应该发生变化/加载

App.js

function App() {
  const [background, setBackground] = useState('');


  async function fetchBgImage() {
    // getRandomImage returns a link fetched from the api
    setBackground(await getRandomImage());
  }

  useEffect(() => {
    fetchBgImage(); //a method which sets the background image and sets background to image url
  }, []);

  return (
    <div className="App">
      // Here backgound is just an image url
      <img id="background_image" src={background} alt="background image" />
    </div>
  );
}

在现实世界中,该应用程序可以正常运行,并且背景图像可以正确加载并在每页重新加载时进行更改,但是当我使用酶进行测试时,它不会等待设置backgound属性,因此, src属性为空。

App.test.js

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());
});

那我该如何使酶等待图像的src属性被设置?

1 个答案:

答案 0 :(得分:0)

您可以编写一个辅助函数来等待该属性。像这样:

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 ${element.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
});