Angular JS Test驱动开发,具有多个控制器

时间:2016-01-12 11:28:40

标签: angularjs tdd karma-jasmine

我使用Angular JS开发了一个Web应用程序。我在使用TTD方法时需要实现的额外CR很少。我们使用Jasmine和Karma返回单元测试用例。我们目前面临的挑战是当我们尝试为多个控制器编写单元测试用例时。我在Home Controller&amp ;;上有一个主页面。它在另一个控制器中有一个广播事件。当我编写单元测试用例时,没有初始化具有此广播事件的控制器的对象。

有没有办法将第二个控制器作为依赖对象注入。非常感谢使用参考样本链接或演示代码的答案。

3 个答案:

答案 0 :(得分:9)

你说你正在使用Jasmine和Karma,所以我假设你是单元测试。如果你是" unit"测试你应该在模拟,间谍,所有注入的服务时单独测试每个控制器。

    beforeEach(inject(function ($rootScope, $controller) {
        rootScope = $rootScope;
        scope = $rootScope.$new();
        controller = $controller('MyCtrl as ctrl', {
            '$scope': scope
        });            
    }));

    it('', function(){

     //Arrange
     controller.counter = 0; // Your controller is listening on scope.$on to update this counter.

     //Act
     rootScope.$broadcast('xyz', {});

     //Assert
     expect(controller.counter == 1).toBe(true);
     rootScope.$broadcast('xyz', {});
     expect(controller.counter == 2).toBe(true);
     rootScope.$broadcast('xyz', {});
     expect(controller.counter == 3).toBe(true);
    });

小心广播。只有域事件(模型更新/删除/创建)或全局(登录,注销)应该通过$广播传播。否则,应该用service +指令替换它。一个例子是角度材料https://material.angularjs.org/latest/api/service/ $ mdDialog,它是一个带有支持服务的指令,可以从任何地方打开/关闭。

答案 1 :(得分:2)

您可以使用$ controller服务注入任何控制器,例如

beforeEach(inject(function ($rootScope, $controller) {
            scope = $rootScope.$new();
            controller = $controller('MyCtrl', {
                '$scope': scope
            });
        }));

在这里查看文档: https://docs.angularjs.org/api/ngMock/service/ $控制器

所以你要做的就是首先注入该控制器,然后注入另一个控制器。然后第一个控制器将在第二个实例化时实例化。

答案 2 :(得分:1)

我是角色的新手,似乎可以同时注入多个控制器。但最佳做法是生成一个模拟控制器,其行为与您希望第二个控制器的行为一样。这样可以减少您一次测试的内容。 以下链接可能有助于创建模拟控制器http://www.powdertothepeople.tv/2014/08/28/Mocking-Controller-Instantiation-In-AngularJS-Unit-Test/