Используйте Jasmine, чтобы заглушить обратные вызовы JS на основе значений аргументов
В моем приложении node.js есть метод JS, который я хочу выполнить модульное тестирование. Он делает несколько вызовов метода сервиса, каждый раз передавая этот сервис обратный вызов; обратный вызов накапливает результаты.
Как я могу использовать Jasmine, чтобы заглушить метод службы, чтобы при каждом вызове заглушки вызывался обратный вызов с ответом, определяемым аргументами?
Это (как) метод, который я тестирую:
function methodUnderTest() {
var result = [];
var f = function(response) {result.push(response)};
service_method(arg1, arg2, f);
service_method(other1, other2, f);
// Do something with the results...
}
Я хочу указать, что когда service_method вызывается с arg1 и arg2, заглушка будет вызывать обратный вызов f с конкретным ответом, а когда она вызывается с other1 и other2, она будет вызывать тот же самый обратный вызов с другим конкретным ответом.
Я бы тоже рассмотрел другую структуру. (Я попробовал Nodeunit, но не смог сделать то, что хотел.)
3 ответа
Вы должны быть в состоянии использовать callFake
шпионская стратегия. В Жасмин 2.0 это будет выглядеть так:
describe('methodUnderTest', function () {
it("collects results from service_method", function() {
window.service_method = jasmine.createSpy('service_method').and.callFake(function(argument1, argument2, callback) {
callback([argument1, argument2]);
});
arg1 = 1, arg2 = 'hi', other1 = 2, other2 = 'bye';
expect(methodUnderTest()).toEqual([[1, 'hi'], [2, 'bye']]);
});
});
куда methodUnderTest
возвращает массив результатов.
Поскольку я не уверен, что вы тестируете правильную вещь здесь, вы можете использовать шпион и вызвать spy.argsForCall.
var Service = function () {
};
Service.service_method = function (callback) {
someAsyncCall(callback);
};
function methodUnderTest() {
var result = [];
var f = function(response) {result.push(response)};
Service.service_method(arg1, arg2, f);
Service.service_method(other1, other2, f);
}
в вашем тесте:
it('should test something', function () {
spyOn(Service, 'service_method');
methodUnderTest()
var arg1 = Service.argsForCall[0][0];
var arg2 = Service.argsForCall[0][1];
var f = Service.argsForCall[0][2];
if(arg1==condition1 && arg2==condition2){f(response1)}
});
Вы не можете заглушить это как есть, потому что оно является внутренним для метода.
Вы проверяете не то, что здесь. methodUnderTest
следует проверить, убедившись, что результаты обрабатываются правильно. Обеспечение этого service_method
выполняет обратный вызов с конкретными аргументами - это еще один тест, который должен быть проверен независимо.
Теперь спецификация для methodUnderTest
может быть просто о том, что происходит после этого обратного вызова. Не беспокойтесь, если обратные вызовы работают, потому что вы уже проверяли это в другом месте. Просто беспокойтесь о том, что метод делает с результатами обратного вызова.
Даже если service_method
это из библиотеки или программного кода, который вы не контролируете напрямую, это все еще применяется. Основное правило - проверять код, который вы сами пишете, и полагать, что другие библиотеки следуют тому же правилу.