如何用 jest 模拟和测试链式函数?
How do I mock and test chained function with jest?
我的组件 useEffect 挂钩中有这个函数链。
我将 response/data 设置为我的组件状态,以便我可以在我的组件中呈现数据。
client
.items()
.type("client")
.toObservable()
.subscribe(response => {
setState(response)
})
如何模拟此函数并在我的测试中呈现组件之前调用它?我正在使用 testing-library/react.
响应是
{items: [{},...]}, somethingElse: {}
您可以使用 mockFn.mockReturnThis() 来执行此操作。
client.ts
,模拟真实的第三方模块
const client = {
items: () => {
return client;
},
type: (name: string) => {
return client;
},
toObservable: () => {
return client;
},
subscribe: handler => {
handler();
return client;
}
};
export { client };
在 React 组件中使用 client.ts
模块:
class Component {
private props;
constructor(props) {
this.props = props;
}
public componentDidMount() {
this.props.client
.items()
.type('client')
.toObservable()
.subscribe(response => {
this.setState(response);
});
}
private setState(state) {
console.log(state);
}
}
export { Component };
单元测试,真实client.ts
模块的模拟链方法,将模拟的client
模块注入到您的组件中。
import { Component } from './';
const mockClient = {
items: jest.fn().mockReturnThis(),
type: jest.fn().mockReturnThis(),
toObservable: jest.fn().mockReturnThis(),
subscribe: jest.fn().mockReturnThis()
};
const mockProps = {
client: mockClient
};
const component = new Component(mockProps);
describe('Component', () => {
describe('#componentDidMount', () => {
it('should mount the component and set state correctly', () => {
const mockedResponse = { items: [{}], somethingElse: {} };
mockClient.subscribe.mockImplementationOnce(handler => handler(mockedResponse));
// tslint:disable-next-line: no-string-literal
component['setState'] = jest.fn();
component.componentDidMount();
expect(mockClient.items().type).toBeCalledWith('client');
// tslint:disable-next-line: no-string-literal
expect(component['setState']).toBeCalledWith(mockedResponse);
});
});
});
单元测试结果:
PASS src/mock-function/57719741/index.spec.ts
Component
#componentDidMount
✓ should mount the component and set state correctly (6ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.542s, estimated 2s
我的组件 useEffect 挂钩中有这个函数链。 我将 response/data 设置为我的组件状态,以便我可以在我的组件中呈现数据。
client
.items()
.type("client")
.toObservable()
.subscribe(response => {
setState(response)
})
如何模拟此函数并在我的测试中呈现组件之前调用它?我正在使用 testing-library/react.
响应是
{items: [{},...]}, somethingElse: {}
您可以使用 mockFn.mockReturnThis() 来执行此操作。
client.ts
,模拟真实的第三方模块
const client = {
items: () => {
return client;
},
type: (name: string) => {
return client;
},
toObservable: () => {
return client;
},
subscribe: handler => {
handler();
return client;
}
};
export { client };
在 React 组件中使用 client.ts
模块:
class Component {
private props;
constructor(props) {
this.props = props;
}
public componentDidMount() {
this.props.client
.items()
.type('client')
.toObservable()
.subscribe(response => {
this.setState(response);
});
}
private setState(state) {
console.log(state);
}
}
export { Component };
单元测试,真实client.ts
模块的模拟链方法,将模拟的client
模块注入到您的组件中。
import { Component } from './';
const mockClient = {
items: jest.fn().mockReturnThis(),
type: jest.fn().mockReturnThis(),
toObservable: jest.fn().mockReturnThis(),
subscribe: jest.fn().mockReturnThis()
};
const mockProps = {
client: mockClient
};
const component = new Component(mockProps);
describe('Component', () => {
describe('#componentDidMount', () => {
it('should mount the component and set state correctly', () => {
const mockedResponse = { items: [{}], somethingElse: {} };
mockClient.subscribe.mockImplementationOnce(handler => handler(mockedResponse));
// tslint:disable-next-line: no-string-literal
component['setState'] = jest.fn();
component.componentDidMount();
expect(mockClient.items().type).toBeCalledWith('client');
// tslint:disable-next-line: no-string-literal
expect(component['setState']).toBeCalledWith(mockedResponse);
});
});
});
单元测试结果:
PASS src/mock-function/57719741/index.spec.ts
Component
#componentDidMount
✓ should mount the component and set state correctly (6ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.542s, estimated 2s