2

我们有一个我们称之为 a 的东西CORShttpService,它基本上是$http服务的包装器,但封装了一些我们需要的 CORS 功能。我现在正在为已CORShttpService注入的服务编写一些测试。该服务的代码如下:

CORShttpService({method: requestMethod, url: getUrl(path), data: data}).
    success(function(data, status, headers) {
        //do success stuff
    }).
    error(function(data, status, headers) {
       //do error stuff
    });

我想模拟对 的调用CORShttpService,但我不知道该怎么做。我正在使用 Jasmine,它的spyOn功能需要一个对象来模拟对象上的功能。MyCORShttpService没有附加到任何对象,所以我不知道如何去嘲笑它。是的,我可以$httpBackend用来模拟最终在 中设置的请求CORShttpService,但我不希望它首先进入该服务。我想隔离单元测试并简单地模拟外部调用。有什么方法可以模拟这个只是一个功能的服务吗?

4

2 回答 2

7

当我更多地考虑这一点时,该$httpBackend服务确实为测试请求提供了很多功能。由于 myCORShttpService基本上是一个包装器,我决定如果我对简单的实现$http进行模拟实现,我可能会获得最大的收益。使用此文档来帮助我,我的规范中有以下内容:CORShttpService$http

beforeEach(module(function($provide) {
    $provide.provider('CORShttpService', function() {
        this.$get = function($http) {
            return $http;
        };
    });
}));

因此,我的任何想要CORShttpService注入的服务现在基本上都只是$http注入了,因此我可以使用所有$httpBackend功能而无需担心CORShttpService自身中发现的额外功能。

这适用于我的具体情况,但就模拟只是一个函数的服务的一般解决方案而言,可能可以jasmine.createSpy像 zbynour 的回答中提到的那样做同样的事情。就像是:

beforeEach(module(function($provide) {
    $provide.provider('MyService', function() {
        this.$get = function() {
            return jasmine.createSpy("myService");
        };
    });
}));
于 2013-01-28T19:08:36.587 回答
2

是的,正如您所写的,spyOn可以存根一个函数,但它必须是已经存在的对象的属性。我也同意最好隔离单位。:)

你需要的是jasmine.createSpy. 这样,您可以创建一个裸间谍并像往常一样定义其行为(使用andReturnandCallFake等)。

我认为像下面的代码(也带有jasmine.createSpyObj)云是你想要的:

it ('should do sth', function() {

    var res = jasmine.createSpyObj('res', [ 'success', 'error' ]);
    res.success.andReturn(res);
    res.error.andReturn(res);
    var corsHttpService = jasmine.createSpy().andReturn(res);

    // call the service using corsHttpService
    anotherService(corsHttpService);

    // assert
    expect(corsHttpService).toHaveBeenCalledWith({
        method: requestMethod, 
        url: url,
        data: data});
    expect(res.success).toHaveBeenCalledWith(jasmine.any(Function));
    expect(res.error).toHaveBeenCalledWith(jasmine.any(Function));
});

如果您想走得更远,而不是简单

res.success.andReturn(res);

您可以存储传入的回调

var succCallback;
res.success.andCallFake(function(callback) {
        succCallback = callback;
        return res;
    });

稍后在规范中,您可以调用回调来模拟来自以下的成功结果corsHttpService

succCallback('a-data', 'a-status', 'a-header');

然后可以测试测试服务的“成功的东西”......

于 2013-01-26T12:04:59.977 回答