Ложный роутер.events.subscribe () Angular2

В моем app.component.ts у меня есть следующая функция ngOnInit:

ngOnInit() {
    this.sub = this.router.events.subscribe(e => {
      if (e instanceof NavigationEnd) {
        if (!e.url.includes('login')) {
          this.loggedIn = true;
        } else {
          this.loggedIn = false;
        }
      }
    });
  }

В настоящее время я проверяю, не является ли саб не нулевым, но я хочу протестировать функцию со 100% покрытием.

Я хочу смоделировать объект маршрутизатора, чтобы я мог смоделировать URL-адрес и затем проверить, правильно ли задан this.loggedIn.

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

Ответы на вопрос(4)

которая использует этот метод для реализации события NavigationEnd для тестирования:

import {Injectable} from '@angular/core';
import { NavigationEnd } from '@angular/router';
import {Subject} from "rxjs";

@Injectable()
export class RouterStub {
  public url;
  private subject = new Subject();
  public events = this.subject.asObservable();

  navigate(url: string) {
    this.url = url;
    this.triggerNavEvents(url);
  }

  triggerNavEvents(url) {
    let ne = new NavigationEnd(0, url, null);
    this.subject.next(ne);
  }
}

 DAG10 июл. 2017 г., 14:23
Есть ли у вас какие-либо понятия, как издеватьсяRoutesRecognized вместоNavigationEnd?

но это немного проще, вы можете заменить

public ne = new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login');
  public events = new Observable(observer => {
    observer.next(this.ne);
    observer.complete();
  });

от:

public events = Observable.of( new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login'));

И найдите ниже полный тестовый файл для проверки функции в вопросе:

import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
  async,
  TestBed,
  ComponentFixture
} from '@angular/core/testing';

/**
 * Load the implementations that should be tested
 */
import { AppComponent } from './app.component';

import { NavigationEnd, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';


class MockServices {
  // Router
  public events = Observable.of( new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login'));
}

describe(`App`, () => {
  let comp: AppComponent;
  let fixture: ComponentFixture<AppComponent>;
  let router: Router;

  /**
   * async beforeEach
   */
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ AppComponent ],
      schemas: [NO_ERRORS_SCHEMA],
      providers: [
        { provide: Router, useClass: MockServices },
      ]
    })
    /**
     * Compile template and css
     */
    .compileComponents();
  }));

  /**
   * Synchronous beforeEach
   */
  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    comp    = fixture.componentInstance;

    router = fixture.debugElement.injector.get( Router);

    /**
     * Trigger initial data binding
     */
    fixture.detectChanges();
  });

  it(`should be readly initialized`, () => {
    expect(fixture).toBeDefined();
    expect(comp).toBeDefined();
  });

  it('ngOnInit() - test that this.loggedIn is initialised correctly', () => {
    expect(comp.loggedIn).toEqual(true);
  });

});
 Reddi Rajendra P20 июн. 2018 г., 07:42
Спасибо за предоставление полного файла. полезный

public events = Observable.of( new NavigationEnd(0, 'http://localhost..')); кажется, не работает в соответствии с кармой, котораяжалуется около:

Ошибка: undefined не является объектом (оценивается router.routerState.root) rootRoute @HTTP: // локальный: 9876 / _karma_webpack_ / vendor.bundle.js

Несмотря на (издевались) экземпляр маршрутизатораСобытияобратный вызов подписки был успешно запущен вngOninit() оригинального app.component.ts, то есть основного компонента приложения, который тестируется компанией Karma:

this.sub = this.router.events.subscribe(e => { // successful execution across Karma

Действительно, способ, которым маршрутизатор был осмеян, выглядит неполным, неточным каксостав с точки зрения Кармы: из-заrouter.routerState это оказывается неопределенным во время выполнения.

Вот как Angular Router был «заглушен» именно на моей стороне, в том числеRoutesRecognized События запеченный какObservableв моем случае:

class MockRouter {
    public events = Observable.of(new RoutesRecognized(2 , '/', '/',
                                  createRouterStateSnapshot()));
}

const createRouterStateSnapshot = function () {
    const routerStateSnapshot = jasmine.createSpyObj('RouterStateSnapshot', 
                                                     ['toString', 'root']);
    routerStateSnapshot.root = jasmine.createSpyObj('root', ['firstChild']);
    routerStateSnapshot.root.firstChild.data = {
        xxx: false
    };
    return <RouterStateSnapshot>routerStateSnapshot;
};

чтобы соответствовать чемуngOnInit() тело ожидает, требуяRoutesRecognized событие с глубокой структурой:

ngOnInit() {
   this.router.events.filter((event) => {
        return event instanceof RoutesRecognized;
    }).subscribe((event: RoutesRecognized) => {
        // if (!event.state.root.firstChild.data.xxx) {
        // RoutesRecognized event... to be baked from specs mocking strategy
   });
}

Резюме / краткое содержание моего <package.json> контента:

угловой / маршрутизатор: 5.2.9, карма: 2.0.2, ядро ​​жасмина: 2.6.4, карма-жасмин: 1.1.2

Решение Вопроса

Я нашел ответ, если кто-то ищет его:

import {
  addProviders,
  async,
  inject,
  TestComponentBuilder,
  ComponentFixture,
  fakeAsync,
  tick
} from '@angular/core/testing';
import { AppComponent } from './app.component';
import { Router, ROUTER_DIRECTIVES, NavigationEnd } from '@angular/router';
import { HTTP_PROVIDERS } from '@angular/http';
import { LocalStorage, WEB_STORAGE_PROVIDERS } from 'h5webstorage';
import { NavComponent } from '../nav/nav.component';
import { FooterComponent } from '../footer/footer.component';
import { Observable } from 'rxjs/Observable';

class MockRouter {
  public ne = new NavigationEnd(0, 'http://localhost:4200/login', 'http://localhost:4200/login');
  public events = new Observable(observer => {
    observer.next(this.ne);
    observer.complete();
  });
}

class MockRouterNoLogin {
  public ne = new NavigationEnd(0, 'http://localhost:4200/dashboard', 'http://localhost:4200/dashboard');
  public events = new Observable(observer => {
    observer.next(this.ne);
    observer.complete();
  });
}
 Amit Chigadani07 апр. 2017 г., 17:51
Пожалуйста, предоставьте информацию о вашей конфигурации TestingModule.
 Syed Jafri12 июл. 2018 г., 15:30
Чтобы заставить это работатьprovide фиктивный класс кTestBed. providers: [{provide: Router, useClass: MockRouter]
 kat133019 окт. 2017 г., 23:19
Этот ответ неполон. Пожалуйста, предоставьте объяснение использования.
 Rory Standley06 мар. 2017 г., 15:20
Не могли бы вы показать полный тестовый файл?

Ваш ответ на вопрос