8

我正在尝试了解如何使用 jasmine 和 angularJS 测试我的代码。我编写了一个带有控制器和注入服务的测试项目。现在我想测试控制器并尝试模拟注入的服务。但是我没有找到一种方法来测试我的控制器的“到达”功能。这是我的 jsfiddle:http: //jsfiddle.net/2fwxS/

控制器.js:

angular.module('myApp.controllers', [])
    .controller('MyCtrl', ['$scope', 'MyService', function ($scope, MyService) {
    $scope.User = {};
    $scope.HasUserArrived = false;
    $scope.Arrived = function(firstname, lastname) {
    $scope.HasUserArrived = MyService.Arrive(firstname, lastname);
    return $scope.HasUserArrived;
    }
}]);

服务.js:

var myApp = angular.module('myApp.services', []).
  value('version', '0.1');

myApp.factory('MyService', [function () {
    return {
        HasArrived: false,
        Arrive: function (firstname, lastname) {
            this.HasArrived = false;

            if (firstname && lastname) {
                this.HasArrived = true;
            }

            console.log("User has arrived: " + this.HasArrived);
            return this.HasArrived;
        }
    }
}]);

我发现了一些类似的解释,其中 $provide 可能是正确的解决方案(我如何为这样的角度控制器和服务编写茉莉花测试?)或 createSpy(你如何模拟作为函数的 Angular 服务?)但我不能了解何时需要 $provider.factory 或 $provider.value 或何时应该使用 createSpy?

如果有人可以帮助我理解差异并在我的 jsFiddle ( http://jsfiddle.net/2fwxS/ ) 示例中启动并运行停用的代码,我将不胜感激......

4

1 回答 1

10

您应该使用$provide.value以用模拟的替换原始服务实例:

beforeEach(module(function($provide) {
    var service = { 
        Arrive: function (firstname, lastname) {
            if (firstname && lastname) {
                return true;
            }
        }
    };
    $provide.value('MyService', service);
}));

我真的不知道为什么$provide.value有效,但$provide.factory没有。稍后我将尝试查看 Angular 代码,以便弄清楚。如果我发现了什么,我会更新这个答案。

关于间谍,如果你想测试你的模拟是否以他们应该的方式使用,你应该使用它们。这包括检查参数和调用。这是您的代码更改为使用间谍:

it('checks that Arrived is correctly used', function() {
    // Arrange
    spyOn(service, 'Arrive');

    // Act
    scope.Arrived('Franz', 'Kafka');

    // Assert
    expect(service.Arrive).toHaveBeenCalledWith('Franz', 'Kafka');
});

这是你固定的jsFiddle

于 2013-08-11T20:48:47.343 回答