2015-09-17 3 views
3

У меня есть контроллер, который при строительстве вызывает метод, прикрепленный к $scope:гася метод сферы вызывается в угловой конструкции контроллера с Синоном

angular.module('example', []).controller('exampleCtrl', function($scope) { 
    $scope.method = function() { ... }; 

    $scope.method(); 
}); 

Я хочу, чтобы проверить, что во время строительства контроллера, этот метод вызывается. Я использую жасмин как свою тестовую структуру и sinon.js для моей насмешливой структуры.

describe('tests', function() { 
    var $scope, $controller; 

    beforeEach(inject(function($rootScope, _$controller_) { 
     $scope = $rootScope.$new(); 
     $controller = _$controller_; 
    }); 

    describe('During construction', function() { 
     it('should call "method"', function() { 
      $controller('exampleCtrl', { $scope: $scope }); 

      var methodStub = sinon.stub($scope, 'method'); 

      expect(methodStub.called).toBe(true); 
     }); 
    }); 
}); 

Это терпит неудачу, потому что когда-то $controller() вызываются, он немедленно вызывает $scope.method() прежде, чем я могу незавершенный его. Однако, если я пытаюсь незавершенным метод предварительного строительства,

it('should call "method"', function() { 
    var methodStub = sinon.stub($scope, 'method'); 

    $controller('exampleCtrl', { $scope: $scope }); 

    expect(methodStub.called).toBe(true); 
}); 

Sinon выдает ошибку: TypeError: Cannot read property 'restore' of undefined, потому что $ scope.method не определен, потому что я не назвал конструктором!

Я также попытался заглушить метод непосредственно на $scope, то есть $scope.method = sinon.stub(), но он перезаписывается при построении контроллера.

Итак, можно ли заглушить метод, вызванный во время строительства?

+1

Когда я столкнулся с ситуацией, я обычно перемещаю этот код в службу. Таким образом, он может быть удален до создания контроллера. Я думаю, что в итоге код становится более чистым/более проверяемым. –

+0

Согласен с @Sunil. Вы также можете проверить ожидаемое поведение вашего метода вместо конкретного вызова. У этого есть хороший побочный эффект, который все еще работает, если метод когда-либо реорганизован на части, переименован и т. Д. – ktharsis

ответ

1

Это не сработает, потому что контроллер всегда перезаписывает вас.

Это скорее вопрос чистого кода.

Во-первых, контроллер не должен содержать сложной логики. Обычно он проверяет, чтобы вы издевались над зависимостями и проверяли, правильно ли они вызваны.

Во-вторых, предпочтительным обозначением контроллера является «controller as». Поэтому контроллер является классическим классом JS. Если вы определяете метод в прототипе, вы можете его/ее заглушить/заглушить.

Но в целом требование немного необычно и может указывать на то, что контроллер делает это слишком много.

Смежные вопросы