在 React 组件中开玩笑模拟异步调用
Jest mock async calls inside react component
我是 jest/enzyme 的新手,我正在尝试模拟对 returns Promise 的 ync 函数的调用,该调用是在 componentDidMount 方法中的反应组件内进行的。
测试正在尝试测试 componentDidMount 设置状态中 Promise 返回的数组。
我遇到的问题是测试在数组添加到状态之前完成并通过。我正在尝试使用 'done' 回调让测试等到承诺解决,但这似乎不起作用。
我曾尝试将 expect 调用移至 done() 调用之前的行,但这似乎也不起作用。
谁能告诉我我做错了什么?
正在测试的组件:
componentDidMount() {
this.props.adminApi.getItems().then((items) => {
this.setState({ items});
}).catch((error) => {
this.handleError(error);
});
}
我的测试:
import React from 'react';
import { mount } from 'enzyme';
import Create from '../../../src/views/Promotion/Create';
import AdminApiClient from '../../../src/api/';
jest.mock('../../../src/api/AdminApiClient');
describe('view', () => {
describe('componentDidMount', () => {
test('should load items into state', (done) => {
const expectedItems = [{ id: 1 }, { id: 2 }];
AdminApiClient.getItems.mockImplementation(() => {
return new Promise((resolve) => {
resolve(expectedItems);
done();
});
});
const wrapper = mount(
<Create adminApi={AdminApiClient} />
);
expect(wrapper.state().items).toBe(expectedItems);
});
});
});
你的测试有两个问题。首先你不能像这样嘲笑 AdminApiClient
。 jest.mock
将仅用 undefined
替换模块,因此 getItems.mockImplementation
将无效或会引发错误。也没有必要使用原来的。当您通过道具将其作为参数传递时,您可以直接在测试中创建您的 on mock。其次,如果你使用承诺,你要么必须 return 来自测试的承诺,要么使用 async/await
(docs):
it('', async() = > {
const expectedItems = [{ id: 1 }, { id: 2 }];
const p = Promise.resolve(expectedItems)
AdminApiClient = {
getItems: () = > p
}
const wrapper = mount(
<Create adminApi={AdminApiClient} />
);
await p
expect(wrapper.state().items).toBe(expectedItems);
})
我是 jest/enzyme 的新手,我正在尝试模拟对 returns Promise 的 ync 函数的调用,该调用是在 componentDidMount 方法中的反应组件内进行的。
测试正在尝试测试 componentDidMount 设置状态中 Promise 返回的数组。
我遇到的问题是测试在数组添加到状态之前完成并通过。我正在尝试使用 'done' 回调让测试等到承诺解决,但这似乎不起作用。
我曾尝试将 expect 调用移至 done() 调用之前的行,但这似乎也不起作用。
谁能告诉我我做错了什么?
正在测试的组件:
componentDidMount() {
this.props.adminApi.getItems().then((items) => {
this.setState({ items});
}).catch((error) => {
this.handleError(error);
});
}
我的测试:
import React from 'react';
import { mount } from 'enzyme';
import Create from '../../../src/views/Promotion/Create';
import AdminApiClient from '../../../src/api/';
jest.mock('../../../src/api/AdminApiClient');
describe('view', () => {
describe('componentDidMount', () => {
test('should load items into state', (done) => {
const expectedItems = [{ id: 1 }, { id: 2 }];
AdminApiClient.getItems.mockImplementation(() => {
return new Promise((resolve) => {
resolve(expectedItems);
done();
});
});
const wrapper = mount(
<Create adminApi={AdminApiClient} />
);
expect(wrapper.state().items).toBe(expectedItems);
});
});
});
你的测试有两个问题。首先你不能像这样嘲笑 AdminApiClient
。 jest.mock
将仅用 undefined
替换模块,因此 getItems.mockImplementation
将无效或会引发错误。也没有必要使用原来的。当您通过道具将其作为参数传递时,您可以直接在测试中创建您的 on mock。其次,如果你使用承诺,你要么必须 return 来自测试的承诺,要么使用 async/await
(docs):
it('', async() = > {
const expectedItems = [{ id: 1 }, { id: 2 }];
const p = Promise.resolve(expectedItems)
AdminApiClient = {
getItems: () = > p
}
const wrapper = mount(
<Create adminApi={AdminApiClient} />
);
await p
expect(wrapper.state().items).toBe(expectedItems);
})