Angular 具有多个控制器的 JS 测试驱动开发
Angular JS Test driven Development with multiple controllers
我使用 Angular JS 开发了一个网络应用程序。我几乎没有得到需要在使用 TTD 方法时实施的额外 CR。我们有 return 个使用 Jasmine 和 Karma 的单元测试用例。当前我们面临的挑战是当我们尝试为多个控制器编写单元测试用例时。我在家庭控制器上有一个主页 return,它在另一个控制器中有一个广播事件。当我为具有此广播事件的控制器编写单元测试用例对象时,未初始化。
有没有办法将第二个控制器作为依赖对象注入。非常感谢带有参考示例 link 或演示代码的答案。
您可以使用 $controller 服务注入任何控制器,例如
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller('MyCtrl', {
'$scope': scope
});
}));
在此处查看文档:
https://docs.angularjs.org/api/ngMock/service/$控制器
所以你要做的是先注入那个控制器,然后是你的另一个控制器。那么第一个控制器将在第二个控制器被实例化时被实例化。
我是新手angular,好像可以一次注入多个controller。然而,最佳做法是生成一个模拟控制器,其行为与您期望第二个控制器的行为一样。这减少了您一次要测试的事物的数量。
以下 link 可能有助于创建模拟控制器,http://www.powdertothepeople.tv/2014/08/28/Mocking-Controller-Instantiation-In-AngularJS-Unit-Test/ .
你说你正在使用 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);
});
请注意广播。只有域事件(模型 updated/deleted/created)或全局事件(登录、注销)应该通过 $broadcast 传输。否则,应将其替换为 service + 指令。一个示例是 angular material https://material.angularjs.org/latest/api/service/$mdDialog,它是 1 个指令,带有支持服务,可以从任何地方 open/closed。
我使用 Angular JS 开发了一个网络应用程序。我几乎没有得到需要在使用 TTD 方法时实施的额外 CR。我们有 return 个使用 Jasmine 和 Karma 的单元测试用例。当前我们面临的挑战是当我们尝试为多个控制器编写单元测试用例时。我在家庭控制器上有一个主页 return,它在另一个控制器中有一个广播事件。当我为具有此广播事件的控制器编写单元测试用例对象时,未初始化。
有没有办法将第二个控制器作为依赖对象注入。非常感谢带有参考示例 link 或演示代码的答案。
您可以使用 $controller 服务注入任何控制器,例如
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller('MyCtrl', {
'$scope': scope
});
}));
在此处查看文档: https://docs.angularjs.org/api/ngMock/service/$控制器
所以你要做的是先注入那个控制器,然后是你的另一个控制器。那么第一个控制器将在第二个控制器被实例化时被实例化。
我是新手angular,好像可以一次注入多个controller。然而,最佳做法是生成一个模拟控制器,其行为与您期望第二个控制器的行为一样。这减少了您一次要测试的事物的数量。 以下 link 可能有助于创建模拟控制器,http://www.powdertothepeople.tv/2014/08/28/Mocking-Controller-Instantiation-In-AngularJS-Unit-Test/ .
你说你正在使用 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);
});
请注意广播。只有域事件(模型 updated/deleted/created)或全局事件(登录、注销)应该通过 $broadcast 传输。否则,应将其替换为 service + 指令。一个示例是 angular material https://material.angularjs.org/latest/api/service/$mdDialog,它是 1 个指令,带有支持服务,可以从任何地方 open/closed。