【发布时间】:2017-04-20 19:58:38
【问题描述】:
我有一个使用 fetch 与 API 对话的反应组件,它看起来像这样
class Customer extends Component {
loadCustomer(id) {
fetch(API + '/customers/' + id)
.then((response) => response.json())
.then((js) => {
this.update(js);
})
.catch((error) => {
console.error(error);
}
}
}
我正在尝试为它编写这样的笑话测试
jest.mock(Customer, () => {loadCustomer: jest.fn()});
describe('Customer', () => {
it('renders customer', async () => {
const ret = `
// sample json from the API
`
const result = Promise.resolve(ret);
const tree = renderer.create(
<Customer customerId={125}/>
);
loadCustomer.mockImplementation(() => result);
await result;
expect(tree.toJSON()).toMatchSnapshot();
});
});
这失败了
FAIL tests/Customer.test.js
● Test suite failed to run
TypeError: Cannot read property 'default' of undefined
at Object.<anonymous> (tests/Customer.test.js:12:48)
有问题的线是
jest.mock(Customer, () => {loadCustomer: jest.fn()});
我在这里错过了什么?
编辑
如果我将违规行更改为
jest.mock(Customer, () => ({loadCustomer: jest.fn()}));
我明白了
FAIL tests/Customer.test.js
● Test suite failed to run
TypeError: Cannot read property 'default' of undefined
at Object.<anonymous> (tests/Customer.test.js:12:48)
at process._tickCallback (internal/process/next_tick.js:103:7)
编辑
如果我像这样模拟fetch 方法
beforeEach(() => {
global.fetch = jest.fn().mockImplementation(() => {
var p = new Promise((resolve, reject) => {
resolve({
json: function() {
return { // some json }
}
return p;
});
});
});
describe('Customer', () => {
it('renders customer', async () => {
const tree = renderer.create(
<Customer customerId={125}/>
).toJSON();
await tree;
expect(tree).toMatchSnapshot();
});
});
那么测试不会等待获取完成。
【问题讨论】:
-
您在模拟客户中没有返回任何内容。试试
jest.mock(Customer, () => ({loadCustomer: jest.fn()})); -
这不起作用,因为
jest.mock需要一个作为模块路径的字符串,然后将其替换为作为第二个参数的函数的结果。为什么要在组件中模拟一个函数。最好只模拟fetch。 -
谢谢,确实解决了问题。我确实尝试在
beforeEach块中模拟全局提取。但是如何在it函数中等待异步获取调用完成? -
@AndreasKöberle 我添加了模拟全局获取函数的尝试!
-
啊,我看到了问题,可以解决了。