1

我目前正在尝试学习如何对角度代码进行单元测试,并且我正在使用 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 永远不会更新。谁能看到我在哪里搞砸了?

4

0 回答 0