监视使用 $http get 用于检查功能的工厂被称为
Spying on factory which uses $http get to use to check function is callled
我编写了一个使用 $http get 方法检索 json 数据的工厂。现在我正在尝试为工厂添加一个单元测试来检查函数是否被调用
这是我的工厂
.factory('dataFactory',function($http){
function getData(){
var request = $http({
method: 'GET',
url: 'http://localhost/data.json'
});
return request;
}
var service = {
getData : getData
};
return service;
});
这是我的控制器
.controller('jsonController',function($scope,$state,$stateParams,stringService,dataFactory){
dataFactory.getData()
.then(function(response){
if(response){
$scope.result = response.data.record;
console.log(response.data.record);
} else {
// empty data message
}
})
.catch(function(error){
console.log('something went wrong', error);
});
});
这是我的测试
describe('Testing factory', function() {
beforeEach(module('factories'));
var mySpy;
mySpy = jasmine.createSpy('service');
beforeEach(module(function ($provide){
$provide.value('service',mySpy)
}));
describe('get json List', function () {
it('should return a list', inject(function () {
spyOn(service, 'getData');
expect(service.getData).toHaveBeenCalled();
}));
});
});
它返回错误:
service is not defined
将 factory
定义为 object
可帮助您将控制器中的 return 方法定义为 object function
,例如:
app.factory('dataFactory',function($http){
var factory = {};
factory.getData = function(){
var request = $http({
method: 'GET',
url: 'http://localhost/data.json'
});
return factory;
});
控制器
app.controller("ctrl", function(dataFactory) {
dataFactory.getData(); //worked
})
回答
因为您正在测试 API / GET return,所以您不需要间谍!看起来你的单元测试在技术上就是我所说的 "API" 或 "Integration" 测试——你正在检查来自端点的数据 return。 (这没有什么问题,但这使测试设置有所不同)。
AngularJS 在其 ngMocks 中有一个内置服务,称为 $httpBacked.
代码(规范文件)
describe('Testing Darshuu', function() {
beforeEach(module('Darshuu'));
// var mySpy;
var service = null;
var $httpBackend;
// Setup Spies in beforeEach() blocks!
// mySpy = jasmine.createSpy('service');
beforeEach(module(function($provide){
// $provide.value('service',mySpy)
// $provide => manually provide some object or
// function IN PLACE OF our factory
// Since we're in a Unit Test for the factory,
// we actually want to inject it and NOT mock it
// completely.
// See next beforeEach()
}));
// _..._ notation for injecting in specs
beforeEach(inject(function(_dataFactory_, _$httpBackend_) {
service = _dataFactory_;
$httpBackend = _$httpBackend_;
}));
/*
No call is ever made to getData() so this spec
*should* fail, technically.
*/
// describe('get json List', function () {
// it('should return a list', inject(function () {
// /*
// No call is ever made to getData() so this spec
// *should* fail, technically.
// */
// spyOn(service, 'getData');
// expect(service.getData).toHaveBeenCalled();
// }));
// });
describe("DataFactory", function() {
beforeEach(function() {
// Since you know to expect an $http request, use the testing
// mock for it: $httpBackend
// THEN, mock the response for the "API".
// =====
$httpBackend.whenGET('http://localhost/data.json').respond(200, {
"test": true,
"data": [{id:1, name: "Picard"}, {id: 2, name: "Riker"}, {id: 3, name: "Data"}]
});
})
it('HAS a getData() method', function() {
expect( service.getData ).toBeDefined();
expect( typeof service.getData ).toEqual("function");
})
// BECAUSE there's no AJAX mocking here OR data, it'll fail.
// I have no idea what your hosting/API is like, but this is
// a start I hope!
it("getData() - returns a JSON list (array)", function() {
service.getData().then(function(response) {
expect( response.data ).toBeDefined();
expect( typeof response.data ).toEqual("object");
});
$httpBackend.flush();
})
})
});
Plnkr
我编写了一个使用 $http get 方法检索 json 数据的工厂。现在我正在尝试为工厂添加一个单元测试来检查函数是否被调用
这是我的工厂
.factory('dataFactory',function($http){
function getData(){
var request = $http({
method: 'GET',
url: 'http://localhost/data.json'
});
return request;
}
var service = {
getData : getData
};
return service;
});
这是我的控制器
.controller('jsonController',function($scope,$state,$stateParams,stringService,dataFactory){
dataFactory.getData()
.then(function(response){
if(response){
$scope.result = response.data.record;
console.log(response.data.record);
} else {
// empty data message
}
})
.catch(function(error){
console.log('something went wrong', error);
});
});
这是我的测试
describe('Testing factory', function() {
beforeEach(module('factories'));
var mySpy;
mySpy = jasmine.createSpy('service');
beforeEach(module(function ($provide){
$provide.value('service',mySpy)
}));
describe('get json List', function () {
it('should return a list', inject(function () {
spyOn(service, 'getData');
expect(service.getData).toHaveBeenCalled();
}));
});
});
它返回错误:
service is not defined
将 factory
定义为 object
可帮助您将控制器中的 return 方法定义为 object function
,例如:
app.factory('dataFactory',function($http){
var factory = {};
factory.getData = function(){
var request = $http({
method: 'GET',
url: 'http://localhost/data.json'
});
return factory;
});
控制器
app.controller("ctrl", function(dataFactory) {
dataFactory.getData(); //worked
})
回答
因为您正在测试 API / GET return,所以您不需要间谍!看起来你的单元测试在技术上就是我所说的 "API" 或 "Integration" 测试——你正在检查来自端点的数据 return。 (这没有什么问题,但这使测试设置有所不同)。
AngularJS 在其 ngMocks 中有一个内置服务,称为 $httpBacked.
代码(规范文件)
describe('Testing Darshuu', function() {
beforeEach(module('Darshuu'));
// var mySpy;
var service = null;
var $httpBackend;
// Setup Spies in beforeEach() blocks!
// mySpy = jasmine.createSpy('service');
beforeEach(module(function($provide){
// $provide.value('service',mySpy)
// $provide => manually provide some object or
// function IN PLACE OF our factory
// Since we're in a Unit Test for the factory,
// we actually want to inject it and NOT mock it
// completely.
// See next beforeEach()
}));
// _..._ notation for injecting in specs
beforeEach(inject(function(_dataFactory_, _$httpBackend_) {
service = _dataFactory_;
$httpBackend = _$httpBackend_;
}));
/*
No call is ever made to getData() so this spec
*should* fail, technically.
*/
// describe('get json List', function () {
// it('should return a list', inject(function () {
// /*
// No call is ever made to getData() so this spec
// *should* fail, technically.
// */
// spyOn(service, 'getData');
// expect(service.getData).toHaveBeenCalled();
// }));
// });
describe("DataFactory", function() {
beforeEach(function() {
// Since you know to expect an $http request, use the testing
// mock for it: $httpBackend
// THEN, mock the response for the "API".
// =====
$httpBackend.whenGET('http://localhost/data.json').respond(200, {
"test": true,
"data": [{id:1, name: "Picard"}, {id: 2, name: "Riker"}, {id: 3, name: "Data"}]
});
})
it('HAS a getData() method', function() {
expect( service.getData ).toBeDefined();
expect( typeof service.getData ).toEqual("function");
})
// BECAUSE there's no AJAX mocking here OR data, it'll fail.
// I have no idea what your hosting/API is like, but this is
// a start I hope!
it("getData() - returns a JSON list (array)", function() {
service.getData().then(function(response) {
expect( response.data ).toBeDefined();
expect( typeof response.data ).toEqual("object");
});
$httpBackend.flush();
})
})
});
Plnkr