Pytanie Kontroler testujący jednostki, który używa $ state.transitionTo


w kontrolerze mam funkcję, która używa $state.transitionTo "przekierować" do innego stanu.

teraz utknąłem w testowaniu tej funkcji, zawsze otrzymuję błąd Error: No such state 'state-two'. jak mogę to przetestować? jest całkowicie jasne, że kontroler nic nie wie o innych stanach, ale jak mogę kpić z tego stanu?

jakiś kod:


angular.module( 'mymodule.state-one', [
  'ui.state'
])

.config(function config($stateProvider) {
  $stateProvider.state('state-one', {
    url: '/state-one',
    views: {
      'main': {
        controller: 'MyCtrl',
        templateUrl: 'mytemplate.tpl.html'
      }
    }
  });
})

.controller('MyCtrl',
  function ($scope, $state) {
    $scope.testVar = false;
    $scope.myFunc = function () {
      $scope.testVar = true;
      $state.transitionTo('state-two');
    };

  }
);

describe('- mymodule.state-one', function () {

  var MyCtrl, scope

  beforeEach(module('mymodule.state-one'));

  beforeEach(inject(function ($rootScope, $controller) {

    scope = $rootScope.$new();

    MyCtrl = $controller('MyCtrl', {
      $scope: scope
    });

  }));

  describe('- myFunc function', function () {
    it('- should be a function', function () {
      expect(typeof scope.myFunc).toBe('function');
    });

    it('- should test scope.testVar to true', function () {
      scope.myFunc();
      expect(scope.testVar).toBe(true);
      expect(scope.testVar).not.toBe(false);
    });
  });
});

14
2017-07-10 10:08


pochodzenie




Odpowiedzi:


Zrzeczenie się: Nie zrobiłem tego sam, więc zupełnie nie wiem, czy to zadziała i jest to, o co prosisz.

Z mojego punktu widzenia przychodzą mi na myśl dwa rozwiązania.

1.) W swoich testach skonfiguruj wstępnie $stateProvider przywrócić stan wyszydzony dla state-two To samo robi projekt ui-routera, aby przetestować przejścia stanu.

Widzieć: https://github.com/angular-ui/ui-router/blob/04d02d087b31091868c7fd64a33e3dfc1422d485/test/stateSpec.js#L29-L42

2.) uchwycić i przeanalizować wyjątek i zinterpretować go jako spełniony test, jeśli spróbuje uzyskać dostęp state-two

Drugie podejście wydaje się bardzo hackish, więc głosowałbym na pierwsze.

Są jednak szanse, że całkowicie cię źle zrozumiałem i prawdopodobnie powinienem odpocząć.

Kod rozwiązania:

beforeEach(module(function ($stateProvider) { 
  $stateProvider.state('state-two', { url: '/' }); 
}));

16
2017-07-10 23:52



dzięki! co dodałem do moich testów: beforeEach(module(function ($stateProvider) { $stateProvider.state('state-two', { url: '/' }); })); - johannestroeger
Twój link nie wskazuje już tego, co Twoim zdaniem powinno wskazywać. Może powinieneś wskazać konkretną wersję? - George Stocker♦
Słuszna uwaga. Naprawiono adres URL. - Christoph
To zadziałało dla mnie! :) Dzięki - codeMan


Niedawno zadałem to pytanie jako problem z githubem, a odpowiedź była bardzo pomocna. https://github.com/angular-ui/ui-router/issues/537

Powinieneś zrobić $ rootScope. $ Apply (), a następnie móc testować. Zwróć uwagę, że domyślnie, jeśli korzystasz z templateUrl, otrzymasz "nieoczekiwane żądanie GET" dla widoku, ale możesz to rozwiązać, włączając szablony do testu.

'use strict';

describe('Controller: CourseCtrl', function () {

  // load the controller's module
  beforeEach(module('myApp'));

  // load controller widgets/views/partials
  var views = [
    'views/course.html',
    'views/main.html'
  ];

  views.forEach(function(view) {
    beforeEach(module(view));
  });

  var CourseCtrl,
    scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    CourseCtrl = $controller('CourseCtrl', {
      $scope: scope
    });
  }));

  it('should should transition to main.course', inject(function ($state, $rootScope) {
    $state.transitionTo('main.course');
    $rootScope.$apply();
    expect($state.current.name).toBe('main.course');
  }));
});

5
2017-10-30 14:18





Także jeśli chcesz się spodziewać, że przejście zostało dokonane w taki sposób

expect(state.current.name).toEqual('state-two')

to musisz scope.$apply przed expect() żeby działał


2
2017-09-20 19:22