Liv*_* M. 6 javascript unit-testing jasmine angularjs httpbackend
我有以下控制器(请注意,在实例化时我进行显式调用$scope.getNotifications()):
bla.controller("myctrl", [
"$scope", "$http", "configs", function ($scope, $http, configs) {
$scope.getNotifications = function () {
$http.get("bla/blabla").success(function (data) {
});
};
$scope.removeNotification = function (notification) {
var index = $scope.allNotifications.indexOf(notification);
$scope.allNotifications.splice(index, 1);
};
$scope.getNotifications();
}
]);
Run Code Online (Sandbox Code Playgroud)
然后我做了一些单元测试(注意控制器在每个测试之前被实例化):
describe("blaController", function () {
var scope, $httpBackend;
beforeEach(module('bla'));
beforeEach(inject(function ($controller, $rootScope, _$httpBackend_) {
scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$controller('blaCtrl', { $scope: scope });
}));
afterEach(function(){
//assert
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it("should get all notifications from server when instantiated", function () {
//arrange
$httpBackend.expectGET("api/v1/notifications").respond(200, {});
$httpBackend.flush();
//act - done implicitly when controller is instantiated
});
it("should store all notifications from server on the client when success call to server", function () {
//arrange
$httpBackend.whenGET("api/v1/notifications").respond(200, [{ a: 1, b: 2 }, { c: 3, d: 4 }]);
$httpBackend.flush();
//act - done implicitly when controller is instantiated
//assert
expect(scope.allNotifications).toEqual([{ a: 1, b: 2 }, { c: 3, d: 4 }]);
});
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到现在.所有测试都通过.但是当我添加一个不需要任何HTTP调用的新测试(见下文)时,它会失败,因为afterEach()它会验证expecations但是没有设置期望值removeNotification().这是来自karma的错误消息:
PhantomJS 1.9.7(Windows 8)notificationCenterController removeNotification应该从列表中删除给定的通知FAILED错误:意外的请求:GET api/v1/notifications不再需要更多请求
it("should remove the given notification from the list", function () {
//arrange
var targetObj = { a: 2 };
scope.allNotifications = [{ a: 1 }, targetObj, { a: 3 }];
//act
scope.removeNotification(targetObj);
//assert
expect(scope.allNotifications).toEqual([{ a: 1 }, { a: 3 }]);
});
Run Code Online (Sandbox Code Playgroud)
我的大部分测试都有http调用,因此将验证放在afterEach中是有道理的.我想知道我还有什么其他选择可以避免在N-1测试中复制粘贴afterEach主体.有没有办法告诉$httpBackend忽略任何电话?
您可以将测试包装在描述块中,如下所示。
describe("blaController", function () {
var scope, $httpBackend;
beforeEach(module('bla'));
beforeEach(inject(function ($controller, $rootScope, _$httpBackend_) {
scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$controller('blaCtrl', { $scope: scope });
}));
describe('test http calls', function() {
afterEach(function(){
//assert
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it("should get all notifications from server when instantiated", function () {
//arrange
$httpBackend.expectGET("api/v1/notifications").respond(200, {});
$httpBackend.flush();
//act - done implicitly when controller is instantiated
});
it("should store all notifications from server on the client when success call to server", function () {
//arrange
$httpBackend.whenGET("api/v1/notifications").respond(200, [{ a: 1, b: 2 }, { c: 3, d: 4 }]);
$httpBackend.flush();
//act - done implicitly when controller is instantiated
//assert
expect(scope.allNotifications).toEqual([{ a: 1, b: 2 }, { c: 3, d: 4 }]);
});
});
describe('other tests', function(){
it("should remove the given notification from the list", function () {
//arrange
var targetObj = { a: 2 };
scope.allNotifications = [{ a: 1 }, targetObj, { a: 3 }];
//act
scope.removeNotification(targetObj);
//assert
expect(scope.allNotifications).toEqual([{ a: 1 }, { a: 3 }]);
});
});
});
Run Code Online (Sandbox Code Playgroud)