Вы не хотите передавать параметр в вашу фиктивную функцию, параметры, которые передаются вашей фиктивной функции, должны контролироваться фрагментом кода, который вы тестируете.То, что вы хотите сделать, это изменить поведение насмешки между выполнениями фиктивной функции.
Давайте предположим, что вы пытаетесь протестировать этот фрагмент кода:
// 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();
});
});