Angular ui-使用mocha chai和sinon进行路由测试

Angular ui-route testing using mocha chai and sinon

我需要使用 mocha chai 和 sinon

在 angularjs 中测试以下代码
$scope.send = function() {
    $state.transitionTo('module.sendhome');
}; 

下面是相同的测试用例

it('send' , function () {
    scope.send();
});

在 运行 上面的测试用例出现如下错误。 错误:没有这样的状态'module.sendhome'

在我的测试用例中,需要检查是否使用参数 module.sendhome 调用了 $state.transitionTo。

您需要删除 $statetransitionTo 方法,并在上面写下期望。这将使您的单元测试保持干净和灵活,以免触发 $state.transitionTo 的真正实现(这反过来会触发您遇到的错误)。

var $scope, $state;

beforeEach(function () {
  $state = {};

  module('your_module', function ($provide) {
    $provide.value('$state', $state);
  });

  inject(function ($injector, $controller) {
    $state = $injector.get('$state');
    $scope = $injector.get('$rootScope').$new();

    $controller('your_controller', {
      $scope: $scope,
      $state: $state
    });
  });

  // Stub API
  $state.transitionTo = sinon.stub();
});


it('calls the transitionTo method', function () {
  $scope.send();
  expect($state.transitionTo).to
    .have.been.calledOnce
    .and.calledWith('module.sendhome');
});

编辑

根据 not stubbing out things we do not own 的概念(我不完全同意,但为了争论起见,我同意)。

不要stub$state.transitionTo,而是spy

现在 - 您必须注册一个符合您预期的状态,以免 $state.transitionTo 崩溃。

var stateProvider;

beforeEach(function () {
  module('ui.router', function ($stateProvider) {
    stateProvider = $stateProvider;
  });

  /** The rest of your beforeEach block **/ 

  stateProvider.state('module.sendhome', {});
});

然后在你的it中:

it('calls the transitionTo method with the correct params', function () {
  var spy = sinon.spy($state, 'transitionTo');
  $scope.send();
  expect(spy).to
    .have.been.calledOnce
    .and.calledWith('module.sendhome');
});

编辑#2

如果您想确保在调用 $scope 方法后得到正确的 state,我会研究 this awesomely awesome stateMock

stateMock 作为另一个模块注入到您自己的模块之前,并编写期望,例如:

afterEach(function () {
  $state.ensureAllTransitionsHappened();
});

it('should travel to the correct state', function () {
  $state.expectTransitionTo('module.sendhome');
  $scope.send();
});