Angular 单元测试承诺
Angular unit testing promises
我是 promises 的新手,实际代码似乎可以正常工作,但我也在尝试编写单元测试...
这是我的控制器:
appModule.controller('MyController', function($scope, myService, $timeout, mySecondService) {
$scope.accept = false;
$scope.loading = false;
$scope.text = 'Some text';
$scope.testCall = function() {
$scope.person = true;
$scope.text = '';
$scope.loading = true;
myService.getWeather()
.then(function(data) {
if (data.valid===true) {
$timeout(function(){
$scope.loading = false;
$scope.accept = true;
$timeout(function(){
$scope.customer.cart = false;
}, 1400);
}, 1500);
}
else {
$scope.person = false;
$scope.newMessage = mySecondService.getItem();
}
}, function(error) {
$scope.person = false;
$scope.newMessage = mySecondService.getItem();
});
}
});
控制器规格:
beforeEach(module('myApp'));
describe("MyController Tests", function() {
var scope;
var ctrl;
var customerInfo = {
"ID" : "212143513",
"firstName" : "Lewis",
"lastName" : "Noel"
};
beforeEach(inject(function($rootScope, $controller, myService) {
scope = $rootScope.$new();
rootScope = $rootScope;
mockMyService = myService;
ctrl = $controller('MyController', {$scope:scope, myService:mockMyService});
spyOn(scope, 'testCall').and.callThrough();
}));
it("On controller load, initialise variables", function() {
expect(scope.text).toEqual('Some text');
expect(scope.loading).toEqual(false);
expect(scope.accept).toEqual(false);
});
});
以上测试了 $scope 的初始化,但服务中没有任何内容...
这是我的服务:
appModule.factory('myService', function ($http, $q) {
return {
getWeather: function() {
return $http.get('/cart/customerCart/546546')
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
}
else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});
如果您询问一般情况下如何测试服务,我会这样做:
describe("myService", function() {
var myService;
beforeEach(inject(function($rootScope, _myService_) {
myService = _myService_;
}));
it("On controller load, initialise variables", function() {
var result;
myService.getWeather().then( function (data) {
result = data;
});
$rootScope.$apply();
expect(result).toEqual(whatever);
});
});
备注:
- 您可以使用 _myService_ 下划线技巧获取服务 myService 而无需创建具有该名称的局部变量 (see docs)。
- 您需要调用 $rootScope.$apply() 来刷新测试中的承诺。 see docs
编辑:
你错误地使用了承诺,我会重构你的工厂(未经测试):
appModule.factory('myService', function ($http, $q) {
return {
getWeather: function() {
var defer = $q.defer();
$http.get('/cart/customerCart/546546')
.then(function(response) {
if (typeof response.data === 'object') {
defer.resolve(response.data);
}
else {
// invalid response
defer.reject(response.data);
}
}, function(response) {
// something went wrong
defer.reject(response.data);
});
return defer.promise;
}
};
});
我是 promises 的新手,实际代码似乎可以正常工作,但我也在尝试编写单元测试...
这是我的控制器:
appModule.controller('MyController', function($scope, myService, $timeout, mySecondService) {
$scope.accept = false;
$scope.loading = false;
$scope.text = 'Some text';
$scope.testCall = function() {
$scope.person = true;
$scope.text = '';
$scope.loading = true;
myService.getWeather()
.then(function(data) {
if (data.valid===true) {
$timeout(function(){
$scope.loading = false;
$scope.accept = true;
$timeout(function(){
$scope.customer.cart = false;
}, 1400);
}, 1500);
}
else {
$scope.person = false;
$scope.newMessage = mySecondService.getItem();
}
}, function(error) {
$scope.person = false;
$scope.newMessage = mySecondService.getItem();
});
}
});
控制器规格:
beforeEach(module('myApp'));
describe("MyController Tests", function() {
var scope;
var ctrl;
var customerInfo = {
"ID" : "212143513",
"firstName" : "Lewis",
"lastName" : "Noel"
};
beforeEach(inject(function($rootScope, $controller, myService) {
scope = $rootScope.$new();
rootScope = $rootScope;
mockMyService = myService;
ctrl = $controller('MyController', {$scope:scope, myService:mockMyService});
spyOn(scope, 'testCall').and.callThrough();
}));
it("On controller load, initialise variables", function() {
expect(scope.text).toEqual('Some text');
expect(scope.loading).toEqual(false);
expect(scope.accept).toEqual(false);
});
});
以上测试了 $scope 的初始化,但服务中没有任何内容...
这是我的服务:
appModule.factory('myService', function ($http, $q) {
return {
getWeather: function() {
return $http.get('/cart/customerCart/546546')
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
}
else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});
如果您询问一般情况下如何测试服务,我会这样做:
describe("myService", function() {
var myService;
beforeEach(inject(function($rootScope, _myService_) {
myService = _myService_;
}));
it("On controller load, initialise variables", function() {
var result;
myService.getWeather().then( function (data) {
result = data;
});
$rootScope.$apply();
expect(result).toEqual(whatever);
});
});
备注:
- 您可以使用 _myService_ 下划线技巧获取服务 myService 而无需创建具有该名称的局部变量 (see docs)。
- 您需要调用 $rootScope.$apply() 来刷新测试中的承诺。 see docs
编辑: 你错误地使用了承诺,我会重构你的工厂(未经测试):
appModule.factory('myService', function ($http, $q) {
return {
getWeather: function() {
var defer = $q.defer();
$http.get('/cart/customerCart/546546')
.then(function(response) {
if (typeof response.data === 'object') {
defer.resolve(response.data);
}
else {
// invalid response
defer.reject(response.data);
}
}, function(response) {
// something went wrong
defer.reject(response.data);
});
return defer.promise;
}
};
});