【问题标题】:Jasmine angularjs - spying on a method that is called when controller is initializedJasmine angularjs - 监视初始化控制器时调用的方法
【发布时间】:2013-04-05 17:38:29
【问题描述】:

我目前正在使用 Jasmine 和 Karma(Testacular) 和 Web Storm 来编写单元测试。我无法监视初始化控制器时立即调用的方法。是否可以窥探控制器初始化时调用的方法?

我的控制器代码,我试图监视的方法是getServicesNodeList()

myApp.controller('TreeViewController', function ($scope, $rootScope ,$document, DataServices) {
    $scope.treeCollection  =  DataServices.getServicesNodeList();
    $rootScope.viewportHeight = ($document.height() - 100) + 'px';
});

这是测试规范:

describe("DataServices Controllers - ", function () {

beforeEach(angular.mock.module('myApp'));
describe("DataServicesTreeview Controller - ", function () {


    beforeEach(inject(function ($controller, $rootScope, $document, $httpBackend, DataServices) {
        scope = $rootScope.$new(),
        doc = $document,
        rootScope = $rootScope;
        dataServices = DataServices;

        $httpBackend.when('GET', '/scripts/internal/servicedata/services.json').respond(...);

        var controller = $controller('TreeViewController', {$scope: scope, $rootScope: rootScope, $document: doc, DataServices: dataServices });

        $httpBackend.flush();
    }));

    afterEach(inject(function($httpBackend){
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    }));

    it('should ensure DataServices.getServicesNodeList() was called', inject(function ($httpBackend, DataServices) {
        spyOn(DataServices, "getServicesNodeList").andCallThrough();

        $httpBackend.flush();
        expect(DataServices.getServicesNodeList).toHaveBeenCalled();
    }));


});
});

测试失败,说明该方法没有被调用。我知道我应该模拟 DataServices 并将其传递给测试控制器。但是,无论它是否是模拟方法,在监视该方法时,我似乎仍然会遇到同样的问题。任何人有任何想法或可以指出我处理此问题的正确方法的资源?

【问题讨论】:

    标签: javascript unit-testing angularjs jasmine


    【解决方案1】:

    在编写单元测试时,您应该隔离每段代码。在这种情况下,您需要隔离您的服务并单独对其进行测试。创建服务的模拟并将其传递给您的控制器。

    var mockDataServices = {
        getServicesNodeList: function () {
            return <insert your sample data here > ;
        }
    };
    
    beforeEach(inject(function ($controller, $rootScope, $document) {
        scope = $rootScope.$new(),
        doc = $document,
        rootScope = $rootScope;
    
        var controller = $controller('TreeViewController', {
            $scope: scope,
            $rootScope: rootScope,
            $document: doc,
            DataServices: mockDataServices
        });
    }));
    

    如果发出 $http 请求的是您的服务,您可以从单元控制器测试中删除该部分。编写另一个单元测试来测试服务在初始化时是否进行了正确的 http 调用。

    【讨论】:

    • 感谢 Destron,我最终模拟了这些服务,终于能够让间谍检测到该方法被调用。
    • @JonathanPalumbo 请您与我们分享一下您这次测试的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多