Используйте Jasmine, чтобы заглушить обратные вызовы JS на основе значений аргументов - PullRequest
2 голосов
/ 07 декабря 2011

В моем приложении 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 ]

11 голосов
/ 02 февраля 2014

Вы должны быть в состоянии использовать стратегию 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 возвращает массив результатов.

0 голосов
/ 07 декабря 2011

Поскольку я не уверен, что вы тестируете правильную вещь здесь, вы можете использовать spy и вызвать 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)}

});
0 голосов
/ 07 декабря 2011

Вы не можете заглушить его как есть, потому что он является внутренним для метода.

Вы здесь проверяете не то. methodUnderTest следует проверить, убедившись в правильности обработки результатов. Обеспечение того, что service_method выполняет свой обратный вызов с конкретными аргументами, является еще одним тестом в целом и должно проверяться независимо.

Теперь спецификация для methodUnderTest может быть просто о том, что происходит ПОСЛЕ этого обратного вызова. Не беспокойтесь, если обратные вызовы работают, потому что вы уже проверяли это в другом месте. Просто беспокойтесь о том, что метод делает с результатами обратного вызова.

Даже если service_method взят из библиотеки или программного кода, которым вы напрямую не управляете, это все равно применяется. Основное правило - проверять код, который вы сами пишете, и полагать, что другие библиотеки следуют тому же правилу.

...