Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 测试使用Jest和Ezyme更改状态的异步组件DidMount_Javascript_Reactjs_Testing_Jestjs_Enzyme - Fatal编程技术网

Javascript 测试使用Jest和Ezyme更改状态的异步组件DidMount

Javascript 测试使用Jest和Ezyme更改状态的异步组件DidMount,javascript,reactjs,testing,jestjs,enzyme,Javascript,Reactjs,Testing,Jestjs,Enzyme,我在代码中所做的一切就是在运行componentDidMount时,向GitHub发出axios get请求,并将一些数据设置回状态。但是,当我运行测试时,它仍然表示状态为空数组 以下是我的组件: export default class HelloWorld extends Component { constructor(props) { super(props) this.state = { goodbye: false,

我在代码中所做的一切就是在运行
componentDidMount
时,向GitHub发出axios get请求,并将一些数据设置回状态。但是,当我运行测试时,它仍然表示状态为空数组

以下是我的组件:

export default class HelloWorld extends Component {
    constructor(props) {
        super(props)
        this.state = {
            goodbye: false,
            data: []
        }

    }

    async componentDidMount() {
        await this.func()
    }

    func = async () => {
        let data = await axios.get('https://api.github.com/gists')
        this.setState({data: data.data})
        console.log(this.state)
    }

    goodbye = () => {
        this.setState((state, currentProps) => ({...state, goodbye: !state.goodbye}))
    }

    render() {
        return (
            <Fragment>
                <h1>
                    Hello World
                </h1>
                <button id="test-button" onClick={this.goodbye}>Say Goodbye</button>
                {
                    !this.state.goodbye ? null :
                    <h1 className="goodbye">GOODBYE WORLD</h1>
                }
            </Fragment>
        )
    }
}
导出默认类HelloWorld扩展组件{
建造师(道具){
超级(道具)
此.state={
再见:错,
数据:[]
}
}
异步组件didmount(){
等待这个。func()
}
func=async()=>{
让数据=等待axios.get('https://api.github.com/gists')
this.setState({data:data.data})
console.log(this.state)
}
再见=()=>{
this.setState((state,currentProps)=>({…state,再见:!state.再见}))
}
render(){
返回(
你好,世界
告别
{
!this.state.再见?空:
再见世界
}
)
}
}
这是我的测试:

it('there is data being returned', async () => { 
    const component =  await mount(<HelloWorld />)       

    component.update()

    expect(component.state('data')).toHaveLength(30)

})
it('有数据返回',async()=>{
常量组件=等待装载()
component.update()
expect(component.state('data')).toHaveLength(30)
})

我对开玩笑很陌生,不知道自己做错了什么。这个应用程序是专为测试含有酶的笑话而开发的。如何正确测试此组件?

首先,您需要模拟axios.get(“”)


您可能需要在component.update()之后执行类似于“等待”的操作。

测试从
componentDidMount
运行异步函数的组件(或
useffect
--请参见)必须在运行断言之前等待重新呈现。用于在运行断言之前同步Ezyme的组件树,但不等待承诺或强制重新呈现

一种方法是使用,它在事件循环结束时运行回调,允许承诺以非入侵方式解决问题

以下是您的组件的一个简单示例:

import React from "react";
import Enzyme, {mount} from "enzyme";
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({adapter: new Adapter()});
import mockAxios from "axios";
import HelloWorld from "./HelloWorld";

jest.mock("axios");

describe("HelloWorld", () => {
  beforeEach(() => jest.resetAllMocks());
  
  it("should call `axios.get` and set the response to `state.data`", async () => {
    const mockData = ["foo", "bar", "baz"];
    mockAxios.get.mockImplementationOnce(() => Promise.resolve({data: mockData}));

    const wrapper = mount(<HelloWorld />);
    await new Promise(setImmediate);
    wrapper.update();

    expect(mockAxios.get).toHaveBeenCalledTimes(1);
    expect(wrapper.instance().state.data).toEqual(mockData);
  });
});
测试(
StackUsers.Test.js
):
如果我只想检查状态是否发生变化,为什么我必须模拟axios.get()。@mlisonek您对状态的期望是什么?为什么你认为数据应该有长度(30)?为什么不是50。我在你的测试中没有看到它。我可以看到从前端返回的数据,它是一个由30个对象组成的数组,包含关于gists@mlisonek,你的意思是这是一个真实的数据来源吗?来自网络?
import axios from "axios";
import React from "react";

export default class StackUsers extends React.Component {
  constructor(props) {
    super(props);
    this.state = {users: null};
  }
  
  componentDidMount() {
    this.getUsers();
  }
  
  async getUsers() { 
    const ids = this.props.ids.join(";");
    const url = `https://api.stackexchange.com/2.2/users/${ids}?site=stackoverflow`;
    const res = await axios.get(url);
    this.setState({users: res.data.items});
  }
  
  render() {
    const {users} = this.state;
    return (
      <>
        {users
          ? <ul data-test="test-stack-users-list">{users.map((e, i) => 
              <li key={i}>{e.display_name}</li>
            )}</ul>
          : <div>loading...</div>
        }
      </>
    );
  }
}
import React from "react";
import Enzyme, {mount} from "enzyme";
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({adapter: new Adapter()});
import mockAxios from "axios";
import StackUsers from "../src/components/StackUsers";

jest.mock("axios");

describe("StackUsers", () => {
  beforeEach(() => jest.resetAllMocks());

  it("should load users", async () => {
    mockAxios.get.mockImplementationOnce(() => Promise.resolve({
      data: {
        items: [
          {"display_name": "Jeff Atwood"},
          {"display_name": "Joel Spolsky"},
        ]
      },
      status: 200
    }));

    const wrapper = mount(<StackUsers ids={[1, 4]} />);
    let users = wrapper
      .find('[data-test="test-stack-users-list"]')
      .hostNodes()
    ;
    expect(users.exists()).toBe(false);

    await new Promise(setImmediate);
    wrapper.update();

    expect(mockAxios.get).toHaveBeenCalledTimes(1);
    users = wrapper
      .find('[data-test="test-stack-users-list"]')
      .hostNodes()
    ;
    expect(users.exists()).toBe(true);
    expect(users.children()).toHaveLength(2);
    expect(users.children().at(0).text()).toEqual("Jeff Atwood");
    expect(users.children().at(1).text()).toEqual("Joel Spolsky");
  });
});
{
  "dependencies": {
    "axios": "^0.18.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6"
  },
  "devDependencies": {
    "enzyme": "3.9.0",
    "enzyme-adapter-react-16": "1.12.1",
    "jest": "24.7.1",
    "jest-environment-jsdom": "24.7.1"
  }
}