我有一个执行HTTP POST的简单控制器和服务。控制器有.success和.error回调,我试图编写一些单元测试:
致电btnClick:
<button ng-click="btnClick('cart')">Click</button>
控制器:
app.controller('MyController', function($scope, myService, $timeout) {
$scope.btnClick = function (action) {
$scope.postData = {"ID": $scope.myId, "user": $scope.myUser};
$scope.cartRequest = function() {
$scope.disabled = true;
$scope.myText = '';
myService.postAction('cart', $scope.postData)
.success(function (data, status, headers, config) {
$timeout(function(){
$scope.disabled = false;
$scope.myText = 'Inside Timeout';
$timeout(function(){
$scope.hideBtn = true;
}, 1400);
}, 1500);
})
.error(function (data, status, headers, config) {
$scope.cartError();
});
};
switch(action) {
case "cart":
$scope.cartRequest();
break;
}
};
为MyService:
app.factory('MyService', function ($http) {
return {
postAction: function(uri, postData) {
return $http({
method: 'POST',
url: '/cartInfo/' + uri,
data: postData,
headers: {'Content-Type': 'application/json'}
});
}
};
});
});
我的测试:
describe('Cart API: can get cart details', function () {
var myService, httpBackend;
var customerInfo = {
"accountId" : "12345678901",
"userName" : "MyTestUser",
"firstName" : "Joe",
"lastName" : "Bloggs"
};
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('MyController', {$scope:scope});
spyOn(scope, 'btnClick').and.callThrough();
inject(function ($httpBackend, _MyService_, $timeout) {
MyService = _MyService_;
httpBackend = $httpBackend;
timeout = $timeout;
});
}));
it('should check if a user is already logged in', function () {
scope.customer = customerInfo;
scope.btnClick('cart');
var returnData = {};
var result = {};
var mockData = { "accountId" : scope.customer.accountId, "userName" : scope.customer.userName};
httpBackend.expectPOST('/cartInfo/cart', mockData, function () {
return {
'Content-Type': 'application/json'
};
}).respond(200, returnData);
myService.postAction('unlock', mockData).success(function (response) {
console.log("hello");
timeout.flush(1501);
scope.$apply();
expect(scope.disabled).toBeFalsy();
expect(scope.myText).toEqual('Inside Timeout');
});
});
});
似乎我的测试中的.success块永远不会像2所期望的那样被调用:
expect(scope.disabled).toBeFalsy();
expect(scope.myText).toEqual('Inside Timeout');
似乎没有跑。
答案 0 :(得分:1)
规范中的承诺假设规格应为asynchronous。但Angular的承诺必须经过测试synchronously:
myService.postAction('unlock', mockData);
$rootScope.$digest();
timeout.flush();
// can be omitted if scope watchers don't affect the spec
// scope.$apply();
expect(scope.disabled).toBeFalsy();
expect(scope.myText).toEqual('Inside Timeout');