我对我的一个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)
语法)。
答案 0 :(得分:1)
对.then()
使用$http
时,第一个参数不会是来自服务器的数据。
它将是您看到的包装器对象,服务器中的数据将位于.data
。
您的服务与测试之间没有任何区别。您可能会感到困惑,并认为您服务中的data
参数是来自服务器的数据,它不是。
因此,是的,您必须在测试中使用response.data
并在服务中使用data.data
。但我建议您将服务中的data
参数重命名为response
以保持一致。