例如我有
import React from 'react';
import { getProducts } from 'api/getProducts';
export class Example extends React.Component {
state = {
items: []
};
componentDidMount() {
this.fetchProducts();
}
fetchProducts = async () => {
const { products: items } = this.state;
if (items.length > 0) {
return; //TEST COVERAGE HERE MISSING
}
try {
const { result } = await getProducts('/api/product/1');
this.setState({ items: result });
} catch (e) {
// no-op
}
};
render() {
const { items } = this.state;
return <div>{items}</div>;
}
}
我的测试用例缺少覆盖,如果items
已经存在,它会提前返回。
import React from 'react';
import { getProducts } from 'api/getProducts';
import { Example } from './Example';
jest.mock('api/getProducts');
describe('Example', () => {
it('do not call getProducts if it already exists in state', async () => {
const wrapper = mount(<Example />);
const instance = wrapper.instance();
instance.setState({
items: [{ id: 1, name: 'kettle' }]
});
await instance.fetchProducts();
//How to spy on getProducts and assert it hasn't been called?
});
});
答案 0 :(得分:1)
您可以使用jest.mock(moduleName, factory, options)方法来模拟api/getProducts
模块。
例如
index.tsx
:
import React from 'react';
import { getProducts } from './api/getProducts';
export class Example extends React.Component {
state: any = {
items: [],
};
componentDidMount() {
this.fetchProducts();
}
fetchProducts = async () => {
// @ts-ignore
const { items } = this.state;
if (items.length > 0) {
return;
}
try {
const { result } = await getProducts('/api/product/1');
this.setState({ items: result });
} catch (e) {
// no-op
}
};
render() {
const { items } = this.state;
return (
<div>
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
}
api/getProducts.ts
:
export async function getProducts(url) {
return { result: [] };
}
index.spec.tsx
:
import React from 'react';
import { Example } from './';
import { mount } from 'enzyme';
import { getProducts } from './api/getProducts';
jest.mock('./api/getProducts.ts', () => {
return {
getProducts: jest.fn(),
};
});
describe('Example', () => {
afterEach(() => {
jest.resetAllMocks();
});
it('should fetch products correctly', async () => {
const wrapper = mount(<Example></Example>);
const instance = wrapper.instance();
wrapper.setState({
items: [{ id: 1, name: 'kettle' }],
});
await instance['fetchProducts']();
expect(getProducts).toBeCalledWith('/api/product/1');
});
});
具有100%覆盖率的单元测试结果:
PASS src/stackoverflow/59241777/index.spec.tsx
Example
✓ should fetch products correctly (56ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.273s, estimated 10s