最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Use Jasmine to stub JS callbacks based on argument values - Stack Overflow

programmeradmin4浏览0评论

I've got a JS method in my node.js app that I want to unit test. It makes several calls to a service method, each time passing that service a callback; the callback accumulates the results.

How can I use Jasmine to stub out the service method so that each time the stub is called, it calls the callback with a response determined by the arguments?

This is (like) the method I'm testing:

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...
}

I want to specify that when service_method is called with arg1 and arg2, the stub will invoke the f callback with a particular response, and when it is called with other1 and other2, it will invoke that same callback with a different particular response.

I'd consider a different framework, too. (I tried Nodeunit, but didn't get it to do what I wanted.)

I've got a JS method in my node.js app that I want to unit test. It makes several calls to a service method, each time passing that service a callback; the callback accumulates the results.

How can I use Jasmine to stub out the service method so that each time the stub is called, it calls the callback with a response determined by the arguments?

This is (like) the method I'm testing:

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...
}

I want to specify that when service_method is called with arg1 and arg2, the stub will invoke the f callback with a particular response, and when it is called with other1 and other2, it will invoke that same callback with a different particular response.

I'd consider a different framework, too. (I tried Nodeunit, but didn't get it to do what I wanted.)

Share Improve this question asked Dec 6, 2011 at 22:49 LadlesteinLadlestein 6,1602 gold badges40 silver badges49 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 15

You should be able to use the callFake spy strategy. In jasmine 2.0 this would look like:

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']]);
  });
});

Where methodUnderTest returns the results array.

You can't stub it as is, because it's private an internal to the method.

You are testing the wrong thing here. methodUnderTest should be tested by ensuring that the results are properly handled. Ensuring that service_method executes it's callback with specific arguments is another test altogether and should be tested independently.

Now the spec for methodUnderTest can simply be about what happens AFTER that callback. Dont worry if the callbacks work, because you've already tested that elsewhere. Just worry about what the method does with the results of the callback.

Even if service_method is from a library or vendored code you don't directly control, this still applies. The rule of thumb is to test code YOU yourself write, and trust that other libraries follow the same rule.

As I'm not sure you're testing the right thing here, you can use a spy and call 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);

}

in your test:

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)

  1. 暂无评论