Use Jasmine to stub JS callbacks based on argument values

拟墨画扇 提交于 2020-01-01 18:59:08

问题


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


回答1:


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.




回答2:


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.




回答3:


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

});


来源:https://stackoverflow.com/questions/8408033/use-jasmine-to-stub-js-callbacks-based-on-argument-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!