【问题标题】:Why is first Jest test causing second test to fail?为什么第一个 Jest 测试会导致第二个测试失败?
【发布时间】:2019-10-23 15:39:51
【问题描述】:

我有一个渲染组件列表的 React 组件。我正在运行一些测试来模拟从 JSONPlaceHolder 加载用户的 axios 模块。一切正常,包括异步测试,它按预期模拟数据。但是,如果您查看下面的代码,只要第一个测试被注释掉,它就会通过?我错过了什么吗?多年来一直在敲我的头。测试之间是否需要进行一些清理?提前致谢。

import { waitForElement } from 'enzyme-async-helpers';
import UsersList from '../UsersList';
import axios from 'axios';

const mockUsers = [
    {
        "id": 1,
        "name": "Leanne Mock",
        "username": "Bret",
        "email": "Sincere@april.biz"
    },
    {
        "id": 2,
        "name": "John Mock",
        "username": "Jospeh",
        "email": "wacky@april.biz"
    }
]

axios.get.mockImplementationOnce(() => Promise.resolve({
    data: mockUsers
}))


describe('<UsersList /> tests:', () => {

        //WHEN I UNCOMMENT THIS TEST THE SECOND TEST FAILS?
        test('It renders without crashing', (done) => {
           // const wrapper = shallow(<UsersList />);
        });

        test('It renders out <User /> components after axios fetches users', async () => {
            const wrapper = shallow(<UsersList />);
            expect(wrapper.find('#loading').length).toBe(1); //loading div should be present


            await waitForElement(wrapper, 'User'); //When we have a User component found we know data has loaded
            expect(wrapper.find('#loading').length).toBe(0); //loading div should no longer be rendered
            expect(axios.get).toHaveBeenCalledTimes(1);

            expect(wrapper.state('users')).toEqual(mockUsers); //check the state is now equal to the mockUsers
            expect(wrapper.find('User').get(0).props.name).toBe(mockUsers[0].name); //check correct data is being sent down to User components
            expect(wrapper.find('User').get(1).props.name).toBe(mockUsers[1].name);
        })

})

我得到的错误信息是:

    The render tree at the time of timeout:
     <div
      id="loading"
    >
       Loading users
    </div>

  console.warn node_modules/enzyme-async-helpers/lib/wait.js:42
    As JSON:
     { node:
       { nodeType: 'host',
         type: 'div',
         props: { id: 'loading', children: ' Loading users ' },
         key: undefined,
         ref: null,
         instance: null,
         rendered: ' Loading users ' },
      type: 'div',
      props: { id: 'loading' },
      children: [ ' Loading users ' ],
      '$$typeof': Symbol(react.test.json) }

Test Suites: 1 failed, 1 total
Tests:       2 failed, 2 total

【问题讨论】:

  • 您是否尝试过删除done 参数?
  • 嗨,Doug - 在它没有“完成”之前是的。只是偶然留下了它,因为我试图使用 done() 来查看是否有帮助。一旦我注意到 - 如果我将第一个测试移到第二个测试之下 - 那么所有测试都会通过。这几乎就像第一个测试还没有完成渲染或其他什么,导致第二个测试失败。
  • 你试过axis.get.mockResolvedValue({data: mockUsers})而不是mockImplementationOnce。来源:jestjs.io/docs/en/…
  • 感谢 Doug 欣赏它...成功了 :)

标签: reactjs jestjs enzyme


【解决方案1】:

您只模拟了第一个axios.get 调用,因为您使用的是mockImplementationOnce

当你shallow(&lt;UsersList /&gt;) 两次时,第二次是加载用户超时。

您可以添加一个带有mockResolvedValueOncebeforeEach 方法,以在每次测试之前模拟axios.get

beforeEach(() => {
  axios.get.mockResolvedValueOnce({data: mockUsers});
}

【讨论】:

    【解决方案2】:

    有同样的问题,但我没有提出请求。我正在构建一个客户端 React 应用程序并测试子组件的渲染。我有一个加载到我的 Home 组件上的图像轮播,我正在为它编写测试。如果我注释掉除一个测试(任何测试)之外的所有测试,它就会通过。如果我有多个测试(任何测试组合),它就会失败。我已经尝试过 async/await/waitFor、react-test-renderer、使用 done() - 似乎没有任何改变这种行为。

    import { render, screen } from '@testing-library/react';
    import ImageCarousel from '../carousel/ImageCarousel';
    import localPhotos from '../../data/localPhotos';
    
    // passing in the full array of images is not necessary, it will cause the test to time out
    const testArray = localPhotos.slice(0, 3);
    
    describe('Image Carousel', () => {
        it('renders without error', () => {
          render(<ImageCarousel images={testArray} />);
          const imageCarousel = screen.getByTestId('image-carousel');
          expect(imageCarousel).toBeInTheDocument();
        });
        // it('displays the proper alt text for images', () => {
        //   render(<ImageCarousel images={testArray} />);
        //   const photo1 = screen.getByAltText(localPhotos[0].alt);
        //   const photo2 = screen.getByAltText(localPhotos[1].alt);
        //   expect(photo1.alt).toBe(localPhotos[0].alt);
        //   expect(photo2.alt).toBe(localPhotos[1].alt);
        // });
        // it("displays full-screen icons", () => {
        //   render(<ImageCarousel images={testArray} />);
        //   const fullScreenIcons = screen.getAllByTestId('full-screen-icon');
        //   expect(fullScreenIcons.length).toBe(testArray.length);
        // })
      // shows controls when showControls is true
      // does not show controls when showControls is false
      //   it('displays the proper number of images', () => {
      //     render(<ImageCarousel images={testArray} />);
      //     const carousel_images = screen.getAllByTestId('carousel_image');
      //     expect(carousel_images.length).toBe(testArray.length);
      //   });
      // calls next when clicked
      // calls previous when clicked
      // returns to first image when next is clicked and last image is shown
      // moves to last image when previous is clicked and first image is shown
    });
    
    

    【讨论】:

    • 忘记包含错误信息,无论哪种测试组合都是一样的。 TypeError:无法读取 null 的属性(正在读取 'parentElement')
    猜你喜欢
    • 2023-04-09
    • 2020-02-20
    • 2021-02-27
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多