在setState有机会从componentDidMount呈现之前执行Jest测试

时间:2017-12-12 13:56:02

标签: reactjs jestjs enzyme

我真的很努力让我的测试等到我的组件在执行之前完成渲染。我不确定我的组件是否以不利于测试的方式设置,或者我是否需要其他工具如sinon。

我知道axios-mock-adapter正在运行,因为我可以在componentDidMount中注销响应并查看模拟数据,但响应的日志总是在我在测试中的控制台日志之后。我也尝试拍摄快照,我可以看到div没有被渲染。

我已经使用create-react-app重新创建了这个问题并试图让它变得尽可能简单,希望有人可以帮我解决这个问题......

我的容器:

import React from "react";
import { getUsersApi } from "./api";
import UserList from "./UserList";

type Props = {
  /* */
};

class UserListContainer extends React.Component<Props> {
  async componentDidMount() {
    try {
      const response = await getUsersApi();
      if (response && response.data) {
        console.log("response.data", response.data);
        //when testing I get the fake data
        this.setState({ users: response.data });
      }
    } catch (e) {
      console.error(e);
    }
  }

  constructor(props: any) {
    super(props);
    this.state = {
      users: ""
    };
  }

  render() {
    return <UserList users={this.state.users} />;
  }
}

export default UserListContainer;

清单:

import React from "react";

const UserList = props => (
  <main>
    {props.users
      ? props.users.map(user => {
          return (
            <div className="user-item" key={user.id}>
              {user.name}
            </div>
          );
        })
      : ""}
  </main>
);

export default UserList;

api电话:

import axios from "axios";

export function getUsersApi() {
  return axios.get(`https://jsonplaceholder.typicode.com/users`);
}

我的测试:

import React from "react";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { configure, mount } from "enzyme";
import UserListContainer from "./UserListContainer";
// setup file
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });

// This sets the mock adapter on the default instance
let mock = new MockAdapter(axios);

const users = [
  {
    id: 1,
    name: "Fake User 1"
  },
  {
    id: 2,
    name: "Fake User 2"
  }
];

mock.onGet("https://jsonplaceholder.typicode.com/users").reply(200, users);

describe("UserListContainer", async () => {
  it("gets successful response from API", () => {
    const wrapper = mount(<UserListContainer />);
    console.log(wrapper.update().state("users").length); //returns 0
    console.log(wrapper.find(".user-wrapper").length); //returns 0
    expect(wrapper.find("main").length).toBeGreaterThan(0); //passes
  });
});

我的测试返回:

 PASS  src\UserListContainer.test.js
  UserListContainer
    √ gets successful response from API (8ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.813s, estimated 1s
Ran all test suites.

  console.error node_modules\fbjs\lib\warning.js:33
    Warning: React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers. http://fb.
me/react-polyfills

  console.log src\UserListContainer.test.js:29
    0

  console.log src\UserListContainer.test.js:30
    0

  console.log src\UserListContainer.js:14
    response.data [ { id: 1, name: 'Fake User 1' },
      { id: 2, name: 'Fake User 2' } ]

因此即使响应明显被模拟,组件也不会呈现具有名称的div。我尝试了更新功能(在第一个控制台日志中),但我认为这可能仅适用于浅层渲染?我也试过moxios同样的结果。谢谢

0 个答案:

没有答案