使用笑话进行单元测试,我有以下内容:
jest.mock('../../requestBuilder');
在我的文件夹中,我有一个
__mocks__
我的模拟requestBuilder.js所在的子文件夹。我的笑话单元测试正确地正确调用了我的模拟requestBuilder.js。问题是,我的requestBuilder正在模拟ajax返回,因此我希望能够确定是否应该返回成功或失败的服务器响应。理想情况下,我想将参数传递给我的模拟函数,以确定是否“ ajaxSuccess:是/否”。我怎样才能做到这一点?谢谢
答案 0 :(得分:1)
您不想将参数传递到模拟函数中,传递给模拟函数的参数应由要测试的代码段控制。您要做的是更改模拟函数执行之间的模拟行为。
假设您正在尝试测试以下代码段:
// getStatus.js
const requestBuilder = require('./requestBuilder');
module.exports = () => {
try {
const req = requestBuilder('http://fake.com/status').build();
if (req.ajaxSuccess) {
return {status: 'success'};
} else {
return {status: 'failure'}
}
} catch (e) {
return {status: 'unknown'};
}
};
我们要测试getStatus
是否正确使用requestBuilder
,而不是builder.build()
方法正常工作。验证builder.build()
是一个单独的单元测试的责任。因此,我们为requestBuilder
创建了一个模拟,如下所示:
// __mocks__/requestBuilder.js
module.exports = jest.fn();
此模拟只设置了模拟功能,但未实现该行为。模拟的行为应在测试中定义。这将使您在逐个测试的基础上找到对模拟行为的粒度控制,而不是尝试实现支持每种用例的模拟(例如,控制模拟行为的某些特殊参数)。
让我们使用此新模拟程序实施一些测试:
// getStatus.spec.js
jest.mock('./requestBuilder');
const requestBuilder = require('./requestBuilder');
const getStatus = require('./getStatus');
describe('get status', () => {
// Set up a mock builder before each test is run
let builder;
beforeEach(() => {
builder = {
addParam: jest.fn(),
build: jest.fn()
};
requestBuilder.mockReturnValue(builder);
});
// every code path for get status calls request builder with a hard coded URL,
// lets create an assertion for this method call that runs after each test execution.
afterEach(() => {
expect(requestBuilder).toHaveBeenCalledWith('http://fake.com/status');
});
it('when request builder creation throws error', () => {
// Override the mocking behavior to throw an error
requestBuilder.mockImplementation(() => {
throw new Error('create error')
});
expect(getStatus()).toEqual({status: 'unknown'});
expect(builder.build).not.toHaveBeenCalled();
});
it('when build throws an error', () => {
// Set the mocking behavior to throw an error
builder.build.mockImplementation(() => {
throw new Error('build error')
});
expect(getStatus()).toEqual({status: 'unknown'});
expect(builder.build).toHaveBeenCalled();
});
it('when request builder returns success', () => {
// Set the mocking behavior to return ajaxSuccess value
builder.build.mockReturnValue({ajaxSuccess: true});
expect(getStatus()).toEqual({status: 'success'});
expect(builder.build).toHaveBeenCalled();
});
it('when request builder returns failure', () => {
// Set the mocking behavior to return ajaxSuccess value
builder.build.mockReturnValue({ajaxSuccess: false});
expect(getStatus()).toEqual({status: 'failure'});
expect(builder.build).toHaveBeenCalled();
});
});