开玩笑-单元测试无法进行异步操作

时间:2020-10-07 05:48:40

标签: reactjs unit-testing jestjs enzyme

我有一个 Users 组件,其中包含我从下面所示的服务器获取的usersData,

export const Users: FunctionComponent<any> = () => {
    const [usersData, setUsersData] = useState<TableConfig>();
    let initialLoad = false;
    useEffect(() => {
        if (!usersData) {
            fetchMockUsers().then((result: any) => {
                initialLoad = true;
                setUsersData(result);
            });
        }
    }, [usersData]);
    const handlePageSelection = useCallback((offset, pageSize) => {
        if (!initialLoad) {
            fetchMockUsers(offset, pageSize).then((result: any) => {
                setUsersData(result);
            });
        }
        initialLoad = false;
    }, []);
    return (usersData &&
        <TableWithPagination id="securityUsers" className="user-listing"
           paginationConfig={{ totalItems: 16, handlePageSelection: handlePageSelection }} tableData={usersData} />)
        || <Loader />;
}

我正在尝试为此组件编写单元测试。为此,我最初模拟了fetch调用,并使用一些虚拟数据对其进行了解析。这里发生的是,该行覆盖了 useEffect 内部,但是 TableWithPagination 在DOM中不可用,因为它是根据API响应显示的。

测试文件

import { mount } from 'enzyme';
import React from 'react';
import {Users} from './usersAndUserGroups';

jest.mock('../../../services/common/userService',
    () => ({
        fetchMockUsers: jest.fn().mockResolvedValue({
            headerFields: { key: "userName", value: "User Name", sortable: false },
            rowDataList: [{ userName: "Adriana Ocampo" }]
        })
    }));

describe('Users and User group Listing Component', () => {
    const wrapper = mount(<Users />);

    it('should render in the DOM', () => {
        console.log('WRAPPER', wrapper.debug());

        const container = wrapper.find('.user-listing');

        expect(container.length).toEqual(1); // failing
    });

    
    it('should render in the DOM', () => {
        const container = wrapper.find('TableWithPagination');

        expect(container.length).toEqual(1); // Failed because  TableWithPagination is present in the DOM 
        // ERROR - expect(received).toEqual(expected) // deep equality
    });



}); 

在运行单元测试时出现此错误:-

● Users and User group Listing Component › should render in the DOM

    expect(received).toEqual(expected) // deep equality

    Expected: 1
    Received: 0

      21 |              const container = wrapper.find('.user-listing');
      22 |
    > 23 |              expect(container.length).toEqual(1);
         |                                       ^
      24 |      });
      25 |
      26 |

      at Object.<anonymous> (src/admin-app/components/security/users-and-groups/usersAndUserGroups.test.js:23:28)

  ● Users and User group Listing Component › should render in the DOM

    expect(received).toEqual(expected) // deep equality

    Expected: 1
    Received: 0

      28 |              const container = wrapper.find('TableWithPagination');
      29 |
    > 30 |              expect(container.length).toEqual(1); // Failed because  TableWithPagination is present in the DOM
         |                                       ^
      31 |              // ERROR - expect(received).toEqual(expected) // deep equality
      32 |      });
      33 |


console.log src/admin-app/components/security/users-and-groups/usersAndUserGroups.test.js:18
    WRAPPER <Users>
      <Loader>
        <div className="d-r35-loader">
          <div className="d-r35-loader__spinner">
            <div className="sk-fading-circle">
              <div className="sk-circle1 sk-circle" />
              <div className="sk-circle2 sk-circle" />
              <div className="sk-circle3 sk-circle" />
              <div className="sk-circle4 sk-circle" />
              <div className="sk-circle5 sk-circle" />
              <div className="sk-circle6 sk-circle" />
              <div className="sk-circle7 sk-circle" />
              <div className="sk-circle8 sk-circle" />
              <div className="sk-circle9 sk-circle" />
              <div className="sk-circle10 sk-circle" />
              <div className="sk-circle11 sk-circle" />
              <div className="sk-circle12 sk-circle" />
            </div>
          </div>
          <div className="d-r35-loader__message">
            Loading...
          </div>
        </div>
      </Loader>
    </Users>

  console.error node_modules/react-dom/cjs/react-dom.development.js:88
    Warning: An update to Users inside a test was not wrapped in act(...).

在这里您可以看到包装未使用API​​响应进行更新。仍然显示LOADER

请指出我在这里做错了什么。

2 个答案:

答案 0 :(得分:1)

类似于this case,在声明结果之前,需要等待fetchMockUsers返回的保证。可以从fetchMockUsers间谍那里获取承诺:

const wrapper = mount(<Users />);

expect(fetchMockUsers).toBeCalledTimes(1);
await fetchMockUsers.mock.results[0];

const container = wrapper.find(TableWithPagination);
expect(container.length).toEqual(1)

不能通过名称可靠地标识组件,find应该与TableWithPagination组件而不是字符串一起使用。

答案 1 :(得分:0)

我已经找到了解决上述问题的方法,

 describe('Users and User group Listing Component', () => {
        const wrapper = mount(<Users />);
    
        
        it('should render in the DOM', () => {
            wrapper.update(); // this will update the dom with the server data
            const container = wrapper.find('TableWithPagination');
    
            expect(container.length).toEqual(1); // started working
        });
    
    
    });