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"
}
}