在Angular中测试没有插座的路由导航

时间:2017-03-28 21:27:24

标签: unit-testing angular angular2-routing angular2-testing

我正在编写一个Angular组件的规范,该组件显示一个将导航到另一个页面的按钮。该组件使用Router::navigate(),但本身没有路由器插座。父组件具有插座。在我的规范中,测试应确认单击按钮会路由到正确的路径。

我当前(已损坏)规范尝试使用RouterTestingModule提供到DummyComponent的路由。当在规范中单击按钮时,我收到以下错误:

'Unhandled Promise rejection:', 'Cannot find primary outlet to load 'DummyComponent'', '; Zone:', 'angular', '; Task:', 'Promise.then', '; Value:', Error{__zone_symbol__error: Error{originalStack: 'Error: Cannot find primary outlet to load 'DummyComponent'

显然我正以错误的方式处理这个问题。当组件没有路由器插座时,测试路由器导航的正确方法是什么?

组件(伪代码):

@Component({
    template: `
        Go to the <button (click)="nextPage">next page</button>
    `
})
export class ExampleComponent {
    public myId = 5;

    constructor(private _router: Router);

    public nextPage(): void {
        this._router.navigate(['/example', this.myId]);
    }
}

规范。这不起作用:

const FAKE_ID = 999;

describe('ExampleComponent Test', () => {
    let exampleComponent: ExampleComponent;
    let fixture: ComponentFixture<ExampleComponent>;

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ DummyComponent ],
            imports: [
                RouterTestingModule.withRoutes([
                    { path: 'example/:id', component: DummyComponent }
                ]);
            ]
        });

        fixture = TestBed.createComponent(exampleComponent);
        exampleComponent = fixture.componentInstance;
    });

    it('should route to example/:id', inject([Router, Location], (router: Router, location: Location) => {
        fixture.detectChanges();
        exampleComponent.myId = FAKE_ID;

        const LINK_BUTTON = fixture.debugElement.query(By.css('button'));
        LINK_BUTTON.nativeElement.dispatchEvent(new Event('click'));
        expect(location.path()).toEqual('/example/' + FAKE_ID);
    });
});

1 个答案:

答案 0 :(得分:1)

<router-outlet>需要有一个插座(DummyComponent)。如果DummyComponent是从ExampleComponent导航到的路线,则ExampleComponent应该有出口。您还需要将ExampleComponent添加到声明`

@Component({
  tempalte: `
    <router-outlet></router-outlet>
    <button (click)="nextPage">next page</button>
  `
})
class ExampleComponent{}

declarations: [ ExampleComponent, DummyComponent ]

如果您想避免设置此基础架构只是为了测试导航到的路由,更好的选择可能只是模拟Router,并检查navigate方法是否为用正确的路径调用。

beforeEach(()=>{
  TestBed.configureTestingModule({
    providers: [
      {
        provide: Router,
        useValue: { navigate: jasmine.createSpy('navigate') }
      }
    ]
  })
})

有了这个,您根本不需要配置路由,因为您正在使用假的Router。然后在你的测试中

it('should route to example/:id', inject([Router], (router: Router) => {
  expect(router.navigate).toHaveBeenCalledWith(['/example', FAKE_ID]);
});