【发布时间】:2016-05-03 17:01:52
【问题描述】:
我是测试的新手,我一直在尝试找到对具有服务依赖关系的 AngularJS 控制器进行单元测试的最佳策略。这是源代码:
app.service("StringService", function() {
this.addExcitement = function (str) {
return str + "!!!";
};
});
app.controller("TestStrategyController", ["$scope", "StringService", function ($scope, StringService) {
$scope.addExcitement = function (str) {
$scope.excitingString = StringService.addExcitement(str);
};
}]);
还有我目前正在使用的测试:
describe("Test Strategy Controller Suite", function () {
beforeEach(module("ControllerTest"));
var $scope, MockStringService;
beforeEach(inject(function ($rootScope, $controller) {
$scope = $rootScope.$new();
MockStringService = jasmine.createSpyObj("StringService", ["addExcitement"]);
$controller("TestStrategyController", {$scope: $scope, StringService: MockStringService});
}));
it("should call the StringService.addExcitement method", function () {
var boringString = "Sup";
$scope.addExcitement(boringString);
expect(MockStringService.addExcitement).toHaveBeenCalled();
});
});
这个测试通过了,但我对某些事情感到困惑:如果我更改服务中方法的名称(假设我将其称为addExclamations 而不是addExcitement,但不是在控制器中使用它的位置(仍然说$scope.excitingString = StringService.addExcitement(str);),即使我的控制器现在坏了,我的测试仍然通过。但是,一旦我也更改了控制器中的方法名称,以解决因更改服务的方法名称而导致的实际损坏,我的tests 因为它试图调用旧的 addExcitement 方法而中断。
这表明我需要通过将 jasmine spy 对象行更改为 MockStringService = jasmine.createSpyObj("StringService", ["addExclamations"]); 来手动保持方法名称与服务同步。
所有这一切对我来说似乎都是倒退的,因为我觉得当我更改服务的方法名称而不更改控制器引用该服务名称的方式时我的测试应该会中断。但是我不确定如何在这里两全其美,因为如果我希望我的测试以某种方式跟踪该服务名称,那么当我在两者中更改方法名称时,它就无法再次通过服务和控制器,因为 spyObj 仍然使用旧名称。
任何有关这背后的策略的见解或建议将不胜感激。我将向一些学生教授这一点,并且主要是为了确保我在这方面遵循最佳实践。
【问题讨论】:
标签: angularjs unit-testing jasmine angular-mock