是否可以在注入服务的方法上使用spyOn?

时间:2014-08-04 19:45:12

标签: javascript angularjs jasmine

我正在为Jasmine的控制器编写测试;控制器依赖于我使用beforeEach(inject)注入的服务。但是,当我试图窥探服务中的方法时,我总是会收到以下错误:

spyOn could not find an object to spy upon for replacePod()

我的测试代码如下:

describe('Controller: ResultsController', function () {
    'use strict';
    var ctrl;
    var ResultsService;
    var RouteService;
    var PodService;
    var $scope;
    var httpMock;
    var log;
    // load the controller's module
    beforeEach(module('waApp'));·
    // Initialize the controller and a mock scope
    ····
    beforeEach(inject(function(
            $rootScope,
            $log,
            $controller,
            $httpBackend,
            ResultsService,
            RouteService,
            PodService
        ) {
            $scope =  $rootScope.$new();
            log = $log;
            log.reset();
            httpMock = $httpBackend;
            ctrl = $controller('ResultsController', {
                $scope: $scope,
                ResultsService: ResultsService,
                RouteService: RouteService,
                PodService: PodService
            });
    }));

    it('processRecalculate should call PodService.replacePod', function() {
        $scope.getResults({input:'kitten'});
        spyOn(PodService, 'replacePod');
        expect(PodService.replacePod).toHaveBeenCalled();
    });

这会产生上述错误。我的代码有问题,或者是不可能在注入的服务中监视方法吗?

2 个答案:

答案 0 :(得分:5)

您不会将注入的服务分配给外部变量。因此,间谍时它是未定义的。

inject中的代码应如下所示:

beforeEach(inject(function(
  $rootScope,
  $log,
  $controller,
  $httpBackend,
  _ResultsService_,
  _RouteService_,
  _PodService_
) { 
  $scope = $rootScope.$new();
  log = $log;
  log.reset();
  httpMock = $httpBackend;
  ResultsService = _ResultsService_;
  RouteService = _RouteService_;
  PodService = _PodService_;
  ctrl = $controller('ResultsController', {
    $scope: $scope,
    ResultsService: ResultsService,
    RouteService: RouteService,
    PodService: PodService
  });
}));

希望这有帮助。

答案 1 :(得分:0)

是的,确实可以窥探注入服务中的方法。

我在下面粘贴了一个完整的工作示例jasmine.spec(在coffeescript中),因此您可以看到各种语法示例。

describe 'AppService', ->

    beforeEach ->
        module 'amorphosite'

    beforeEach inject ($injector) ->
        @rootScope = $injector.get '$rootScope'
        @appService = $injector.get 'appService'
        @userService = $injector.get 'userService'
        @restoreService = $injector.get 'restoreService'
        @transitionService = $injector.get 'transitionService'
        @scope = @rootScope.$new()

    describe 'setRootWatch', ->
        describe 'when $stateChangeStart event is triggered and the user is null', ->
            beforeEach ->
                @appService.setRootWatch @scope

            describe 'and the user cannot be restored', ->
                beforeEach ->
                    spyOn(@userService, 'userIsNull').andReturn true
                    spyOn(@restoreService, 'canRestore').andReturn false
                    spyOn @transitionService, 'gotoLogin'

                it 'it should transition to the login state', ->
                    @scope.$broadcast '$stateChangeStart', {name:'[protected-state]'}
                    expect(@transitionService.gotoLogin).toHaveBeenCalled()

            describe 'and the user can be restored', ->
                beforeEach ->
                    spyOn(@userService, 'userIsNull').andReturn true
                    spyOn(@restoreService, 'canRestore').andReturn true
                    spyOn @restoreService, 'restore'

                it 'it should restore the available data', ->
                    @scope.$broadcast '$stateChangeStart', {name:'[protected-state]'}
                    expect(@restoreService.restore).toHaveBeenCalled()