我目前正在尝试学习如何对角度代码进行单元测试,并且我正在使用 Jasmine 来做到这一点。我有以下 AngularJS 特定代码:
/// <reference path="~/Scripts/angular/angular.js"/>
angular.module('testModule', [])
.controller('testController', ['$scope', 'extDataService', function($scope, extDataService) {
//Scope items for testing *******VALUES*******
$scope.testData = ["test1", "test2", "test3"];
$scope.updateTestData = function(indexToUpdate, newValue) {
$scope.testData[indexToUpdate] = newValue;
}
//Scope items for testing *******SERVICES*******
$scope.externalData = null;
$scope.getExternalData = function() {
extDataService.getData().success(function(data) {
$scope.externalData = data;
});
}}])
.factory('extDataService', ['$http', function($http) {
var getData = function() {
return $http.get("/api/testData");
}
return {
"getData": getData
}
}]);
这是我的茉莉花代码:
/// <reference path="~/Scripts/jasmine-samples/TestModule.js"/>
/// <reference path="~/Scripts/angular/angular.js"/>
/// <reference path="~/Scripts/angular/angular-mocks.js"/>
describe("testController", function () {
//load the controller's module
beforeEach(module('testModule'));
//Initialize controller and mock scope for the controller
var testCtrl, scope, dataService, httpBackend;
beforeEach(inject(function ($controller, $rootScope, _extDataService_, _$httpBackend_) {
httpBackend = _$httpBackend_;
scope = $rootScope.$new();
dataService = _extDataService_;
//Get references to $controller service, rather than a particular controller
testCtrl = $controller; //('testController', { $scope: scope, extDataService: dataService}); <-- can be used instead if I wanted a particular controller
}));
it("Should have testData in the scope", function () {
var ctrl = testCtrl('testController', { $scope: scope, extDataService: dataService });
expect(scope.testData.length).toBe(3);
});
it("Should be able to update the testData values", function () {
var ctrl = testCtrl('testController', { $scope: scope, extDataService: dataService });
expect(scope.testData[0]).toBe("test1");
scope.updateTestData(0, "newTestData");
expect(scope.testData[0]).toBe("newTestData");
});
it("Should make a fake data call and update the externalData variable", function() {
httpBackend.expectGET("/api/testData").respond(function(method, url, data, headers) {
return [200, 'fakeResponseData', {}, 'testStatusText'];
});
var ctrl = testCtrl('testController', { $scope: scope, extDataService: dataService });
//expect it to be null first
expect(scope.externalData).toBe(null);
//Update external data, expect it to not be null now
scope.getExternalData();
scope.$digest();
httpBackend.flush();
expect(scope.externalData).not.toBe(null);
//expect(scope.externalData.response).toBe("fakeResponseData");
});
afterEach(function() {
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
});
我的问题出在我最后一个 it 块中被注释掉的期望语句中。我认为在 httpBackend Get 请求上指定响应会更新我的角度范围。但是,我的 specRunner.html 页面上有以下错误:
Expected undefined to be 'fakeResponseData'.
显然,这意味着 $scope.externalData 永远不会更新。谁能看到我在哪里搞砸了?