Przeprowadzam migrację do najnowszej stabilnej wersji ui-routera i korzystam z przechodniów cyklu życia $ przejścia, aby wykonać określoną logikę, gdy pewne nazwy stanów są przenoszone na .Jak testować przejściowe haki z ui-routerem 1.0.x
Tak więc w niektórych moich kontrolerów mam ten kinda rzeczy teraz:
this.$transitions.onStart({ }, (transition) => {
if (transition.to().name !== 'some-state-name') {
//do stuff here...
}
});
W moich testów jednostkowych dla kontrolera, wcześniej bym nadawane zdarzenie zmiany stanu na $ rootScope z niektórych nazw państwa jako zdarzenie mówi, że uderzyło w warunki, które musiałem przetestować.
np.
$rootScope.$broadcast('$stateChangeStart', {name: 'other-state'}, {}, {}, {});
Od tych wydarzeń państwowych są przestarzałe, co jest poprawny sposób teraz wyzwalać $transitions.onStart(...)
haki w testach?
Próbowałem po prostu wywoływać $state.go('some-state-name')
w moich testach, ale nigdy nie mogę trafić własną logikę w funkcji wywołania zwrotnego haka przejścia. Według dokumentów here, wywołanie state.go programowo powinno wywołać przejście, chyba że błędnie odczytuję?
Czy ktoś inny zdołał uzyskać testy jednostkowe dla przejściowych haków w swoich kontrolerach pracujących dla nowego routera Ui 1.0.x?
Pełny przykład mojego kodu sterownika za pomocą haka przejściowy:
this.$transitions.onSuccess({ }, (transition) => {
this.setOpenItemsForState(transition.to().name);
});
Test Spec:
describe('stateChangeWatcher', function() {
beforeEach(function() {
spyOn(vm, 'setOpenItemsForState').and.callThrough();
});
it('should call the setOpenItemsForState method and pass it the state object', function() {
$state.go('home');
$rootScope.$apply();
expect(vm.setOpenItemsForState).toHaveBeenCalledWith('home');
});
});
Mój szpieg nigdy nie jest trafiony, po uruchomieniu aplikacji lokalnie ten hak ma dostać wywoływany zgodnie z oczekiwaniami, więc musi to być coś, co mam nieprawidłowo skonfigurowane w moich testach. Czy jest coś ekstra, czego potrzebuję, aby przejście zakończyło się sukcesem w teście, ponieważ jestem podłączony do zdarzenia onSuccess?
Dzięki
UPDATE
podniosłem to w pokoju ui-router Gitter i jeden z autorów repo wrócił do mnie sprawdzić połączenia do $state.go('home')
w moich testach rzeczywiście biegły sugerując dodając expect($state.current.name).toBe('home');
w mojej specyfikacji testu.
To nie przechodzą na mnie w moim teście, ale nadal jestem w stanie trafić na wezwanie do mojej funkcji w zwrotnego haka przejście:
jestem pewien, jak postępować w tej sprawie, poza instalowaniem polyfill dla starszych zdarzeń $ stateChange, więc mogę użyć mojego poprzedniego kodu, ale wolałbym tego nie robić i wymyślić właściwy sposób testowania haków przejściowych $.
UPDATE 2
następującą odpowiedź estus', mam teraz zgaszone usługę $transitions
a także refactored mojego przejścia obsługi hak do prywatnego funkcji wymienionych w moim kontrolera:
export class NavBarController {
public static $inject = [
'$mdSidenav',
'$scope',
'$mdMedia',
'$mdComponentRegistry',
'navigationService',
'$transitions',
'$state'
];
public menuSection: Array<InterACT.Interfaces.IMenuItem>;
private openSection: InterACT.Interfaces.IMenuItem;
private openPage: InterACT.Interfaces.IMenuItem;
constructor(
private $mdSidenav,
private $scope,
private $mdMedia,
private $mdComponentRegistry,
private navigationService: NavigationService,
private $transitions: any,
private $state
) {
this.activate();
}
private activate() {
this.menuSection = this.navigationService.getNavMenu();
if (this.isScreenMedium()) {
this.$mdComponentRegistry.when('left').then(() => {
this.$mdSidenav('left').open();
});
}
this.setOpenItemsForState(this.$state.$current.name);
this.$transitions.onSuccess({ }, this.onTransitionsSuccess);
}
private onTransitionsSuccess = (transition) => {
this.setOpenItemsForState(transition.to().name);
}
private setOpenItemsForState(stateName: string) {
//stuff here...
}
}
Teraz w moja specyfikacja testu Mam:
describe('Whenever a state transition succeeds', function() {
beforeEach(function() {
spyOn(vm, 'setOpenItemsForState').and.callThrough();
$state.go('home');
});
it('should call the setOpenItemsForState method passing in the name of the state that has just been transitioned to', function() {
expect($transitions.onSuccess).toHaveBeenCalledTimes(1);
expect($transitions.onSuccess.calls.mostRecent().args[0]).toEqual({});
expect($transitions.onSuccess.calls.mostRecent().args[1]).toBe(vm.onTransitionsSuccess);
});
});
Te oczekiwania mijają, ale nadal nie jestem w stanie uderzyć moją wewnętrzną logikę w moim imieniu haka zwrotnego onTransitionsSuccess
funkcję zatelefonować do setOpenItemsForState
Co robię źle tutaj?
UPDATE 3
Dzięki ponownie estu byłem zapominając mogę po prostu zadzwonić do mojego nazwie funkcja hak przejście jest odrębny test:
describe('and the function bound to the transition hook callback is invoked', function(){
beforeEach(function(){
spyOn(vm, 'setOpenItemsForState');
vm.onTransitionsSuccess({
to: function(){
return {name: 'another-state'};
}
});
});
it('should call setOpenItemsForState', function(){
expect(vm.setOpenItemsForState).toHaveBeenCalledWith('another-state');
});
});
A teraz mam 100% populacji :)
Mam nadzieję, że będzie to służyć jako dobry odniesieniu do innych którzy mogą walczyć, aby dowiedzieć się, jak przetestować własne haki przejściowe.
Dzięki za odpowiedź i świetne wyjaśnienie - teraz ma to sens. Nie stoję przed moją maszyną, ale jestem podekscytowany, aby spróbować! – mindparse
Podjęłam próbę rozwiązania problemu, ale wciąż mam problemy, gdy próbuję całkowicie zakryć wezwanie mojego przewodnika. Czuję, że brakuje mi czegoś podstawowego, czy możesz pomóc? – mindparse
Na czym polega problem?Nazwij go po prostu spodziewanymi argami, takimi jak 'this.onTransitionStart ({to:() => ({name: ...})})' i sprawdź swoją wewnętrzną logikę, 'expect (ctrl.setOpenItemItemsForState) .toHaveBeenCalledWith (. ..) '. – estus