Angular 6 - как смоделировать router.events ответ URL в модульном тесте - PullRequest
0 голосов
/ 20 октября 2018

Как видно из заголовка, мне нужно смоделировать router.events в модульном тесте.

В своем компоненте я выполняю некоторые регулярные выражения, чтобы получить первый экземпляр текста между косыми чертами в URL;Например, /pdp/

  constructor(
    private route: ActivatedRoute,
    private router: Router,
  }

this.router.events.pipe(takeUntil(this.ngUnsubscribe$))
      .subscribe(route => {
        if (route instanceof NavigationEnd) {
        // debugger
          this.projectType = route.url.match(/[a-z-]+/)[0];
        }
      });

Мой модуль тестирует ошибку при сборке компонента: Cannot read property '0' of null.Когда я комментирую в отладчике, route, кажется, установлен неправильно, но я устанавливаю его в самом модульном тесте.Я сделал это несколькими разными способами (вдохновленный этим постом: Пересмешивая router.events.subscribe () Angular2 и другие).

Первая попытка:

providers: [
        {
          provide: Router,
          useValue: {
            events: of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit'))
          }
        },
        // ActivatedRoute also being mocked
        {
          provide: ActivatedRoute,
          useValue: {
            snapshot: { url: [{ path: 'new' }, { path: 'edit' }] },
            parent: {
              parent: {
                snapshot: {
                  url: [
                    { path: 'pdp' }
                  ]
                }
              }
            }
          }
        }
]

Вторая попытка (на основе вышеуказанного поста):

class MockRouter {
  public events = of(new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit'))
}

providers: [
        {
          provide: Router,
          useClass: MockRouter
        }
]

Третья попытка (также на основе вышеуказанного поста):

class MockRouter {
  public ne = new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit');
  public events = new Observable(observer => {
    observer.next(this.ne);
    observer.complete();
  });
}

providers: [
        {
          provide: Router,
          useClass: MockRouter
        }
]

Четвертая попытка:

beforeEach(() => {
    spyOn((<any>component).router, 'events').and.returnValue(of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit')))
...

Пятая попытка:

beforeEach(() => {
    spyOn(TestBed.get(Router), 'events').and.returnValue(of({ url:'/pdp/project-details/4/edit' }))
...

Во всех вышеуказанных случаях route не устанавливается;NavigationEnd объект равен:

{ id: 1, url: "/", urlAfterRedirects: "/" }

Мысли?

Ответы [ 3 ]

0 голосов
/ 08 апреля 2019

Это может быть просто:

TestBed.configureTestingModule({
  imports: [RouterTestingModule]
}).compileComponents()

...

const event = new NavigationEnd(42, '/', '/');
TestBed.get(Router).events.next(event);
0 голосов
/ 26 июня 2019

Надеюсь, что это может помочь, вот что я сделал:

const eventsStub = new BehaviorSubject<Event>(null);
    export class RouterStub {
      events = eventsStub;
    }

    beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [AppComponent],
          imports: [RouterTestingModule],
          providers: [
            { provide: HttpClient, useValue: {} },
            { provide: Router, useClass: RouterStub },
            Store,
            CybermetrieCentralizedService,
            TileMenuComponentService,
            HttpErrorService
          ],
          schemas: [NO_ERRORS_SCHEMA]
        }).compileComponents();
        fixture = TestBed.createComponent(AppComponent);
        router = TestBed.get(Router);
        tileMenuService = TestBed.get(TileMenuComponentService);
        component = fixture.componentInstance;
      }));

и затем на тесте я сделал это:

     it('should close the menu when navigation to dashboard ends', async(() => {
        spyOn(tileMenuService.menuOpened, 'next');
        component.checkRouterEvents();
        router.events.next(new NavigationEnd (1, '/', '/'));
        expect(tileMenuService.menuOpened.next).toHaveBeenCalledWith(false);
      }));

это, чтобы проверить, что после навигации по маршруту'/' Я выполняю ожидаемую инструкцию

0 голосов
/ 22 октября 2018

Вот ответ, который я придумал.Я думаю, что я просто недостаточно расширил первый подход (выше):

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

providers: [
    {
      provide: Router,
      useValue: {
        url: '/non-pdp/phases/8',
        events: of(new NavigationEnd(0, 'http://localhost:4200/#/non-pdp/phases/8', 'http://localhost:4200/#/non-pdp/phases/8')),
        navigate: jasmine.createSpy('navigate')
      }
    }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...