Макет углового маршрутизатора со зрителем

Я использую Spectator для написания моих тестов Angular 8 и Jest для их запуска. Я новичок в модульном тестировании внешнего интерфейса, поэтому, возможно, я пропустил что-то простое; любые идеи приветствуются.

У меня есть следующий метод (в Typescript), который возвращает логическое значение в зависимости от того, соответствует ли текущий URL набору путей или нет (за исключением queryParams и фрагментов):

// custom-breadcrumb.component.ts

private blacklistedPaths: string[] = [''];

constructor(private router: Router) {
}

hideBreadcrumb(): boolean {
    let primaryUrlSegmentGroup: UrlSegmentGroup = this.router.parseUrl(this.router.url).root.children['primary'];
    if(primaryUrlSegmentGroup == null){
        return true;
    }
    let urlPath = primaryUrlSegmentGroup.segments.map((segment: UrlSegment) => segment.path).join('/');
    return this.blacklistedPaths.some((path: string) => path === urlPath);
}

а также

// custom-breadcrumb.component.html

<xng-breadcrumb [hidden]="hideBreadcrumb()">
    <ng-container *xngBreadcrumbItem="let breadcrumb">
        ...
    </ng-container>
</xng-breadcrumb>

Теперь я хочу написать тесты с помощью Spectator, которые будут проверять логическое возвращаемое значение на основе нескольких возможных URL-адресов. В Java я бы эмулировалRouter с имитацией объекта и выполните что-то вроде:

when(mockObject.performMethod()).thenReturn(myReturnValue);

Как создать макет для Router? И как мне определить возвращаемые значения дляthis.router.parseUrl(this.router.url).root.children['primary']?

Вот что у меня сейчас есть:

// custom-breadcrumb.component.spec.ts

import {SpectatorRouting, createRoutingFactory} from '@ngneat/spectator/jest';

describe('CustomBreadcrumbComponent', () => {
    let spectator: SpectatorRouting<CustomBreadcrumbComponent>;
    const createComponent = createRoutingFactory({
        component: CustomBreadcrumbComponent,
        declarations: [
            MockComponent(BreadcrumbComponent),
            MockPipe(CapitalizePipe)
        ],
        routes: [{path: ''}]  // I don't think this works
    });

    beforeEach(() => spectator = createComponent());

    it('hideBreadcrumb - hide on homepage', () => {
        // TODO set url path to ''
        expect(spectator.component.hideBreadcrumb()).toBeTruthy();
    });

    it('hideBreadcrumb - show on a page other than homepage', () => {
        //TODO set url path to 'test' for example
        expect(spectator.component.hideBreadcrumb()).toBeFalsy();
    });
});

я знаю это createRoutingFactory поставляет ActivatedRouteStub прямо из коробки, но я не смог сделать с этим ничего значимого.

PS: Я добавил карму в качестве тега, так как он может иметь такое же решение, но исправьте меня, если я ошибаюсь.

1 ответ

Решение

У меня создалось впечатление, что spectator.router возвращал мне издевательство, в то время как я должен был использовать spectator.get<Router>(Router)чтобы получить это. Другая проблема заключалась в том, чтоhideBreadcrumb метод в шаблоне html загружался при создании компонента, а у меня еще не было возможности издеваться над Router. Вот как я это решил:

Установлен detectChanges значение false, чтобы предотвратить загрузку шаблона html и ngOnInit, когда я создаю компонент-наблюдатель следующим образом:

let spectator: SpectatorRouting<CustomBreadcrumbComponent>;
const createComponent = createRoutingFactory({
    detectChanges: false,
    component: CustomBreadcrumbComponent,
    declarations: [ ... ]
});

beforeEach(() => {
    spectator = createComponent()
});

Теперь он не позвонит hideBreadcrumb() еще, что позволяет успешно создать зрителя.

Мой тест таков:

it('hideBreadcrumb - hide on homepage', () => {
    let routerMock = spectator.get<Router>(Router);
    routerMock.parseUrl.andReturn({root: {children: {'primary': {segments: [{path: ''}]}}}});
    spectator.detectChanges();

    expect(spectator.component.hideBreadcrumb()).toBeTruthy();
});

Я извлекаю у зрителя издевательство spectator.get<Router>(Router) и я издеваюсь над возвращаемым значением parseUrlметод. Теперь я разрешаю шаблон html иngOnInit прогрессия путем установки spectator.detectChanges().

Другие вопросы по тегам