$ httpBackend模拟响应超过我告诉它的?

时间:2014-08-17 19:12:35

标签: angularjs

我对我的一个Angular服务进行了Jasmine测试,该服务从服务器获取数据并使其可公开访问。服务器返回JSON,只返回一个对象数组[{...}, {...}, ...]

现在我尝试使用模拟的http后端编写测试:

var mockLibrary = [{}, {}];
beforeEach(inject(function(LibrarySvc) {
    libSvc = LibrarySvc;
}));

it('should fetch the library', function(done) {
    inject(function($httpBackend) {
        $httpBackend.expectGET('/library').respond(200, mockLibrary);

        libSvc.getLibrary()
            .then(function(response) {
                expect(_.isEqual(response, mockLibrary)).toBeTruthy();
            })
          .finally(done);

        $httpBackend.flush();
    });
});

我服务中的代码如下:

var library;
var deferred = $q.defer();

$http.get('/library')
    .then(function(data) {
        library = data;
        deferred.resolve(library);
    }, function(err) {
        deferred.reject(err);
    });

因此,服务将服务器的JSON响应主体分配给内部library变量,并使用它解析承诺。现在,当运行此测试时,它会失败,因为测试中的response不等于mockLibrary。相反,response就是这样:

Object{data: [Object{}, Object{}], status: 200, headers: function (c){ ... }, config: Object{method: 'GET', transformRequest: [...], transformResponse: [...], url: '/library', headers: Object{Accept: ...}}, statusText: ''}

我现在想要的是response.data在测试中,data.data在我的服务逻辑中。

为什么 Angular会这样做?这隐含地暗示我的服务器的JSON响应应该始终是一个哈希,它将实际响应数据保存在data属性中吗?为什么我要将我的服务逻辑调整为Angular测试?还是我错过了什么? $ httpBackend的文档对此事没有帮助。


补充说明:我使用underscore.js进行_.isEqual(...)的深等号检查,并使用Jasmine 2.0进行异步测试(因此function(done)语法)。

1 个答案:

答案 0 :(得分:1)

.then()使用$http时,第一个参数不会是来自服务器的数据。

它将是您看到的包装器对象,服务器中的数据将位于.data

您的服务与测试之间没有任何区别。您可能会感到困惑,并认为您服务中的data参数是来自服务器的数据,它不是。

因此,是的,您必须在测试中使用response.data并在服务中使用data.data。但我建议您将服务中的data参数重命名为response以保持一致。

另见:$http documentation