【问题标题】:Testing route navigation without an outlet in Angular在 Angular 中测试没有插座的路线导航
【发布时间】:2017-03-28 21:27:24
【问题描述】:

我正在为一个 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);
    });
});

【问题讨论】:

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


    【解决方案1】:

    DummyComponent 需要有一个出口 (&lt;router-outlet&gt;)。如果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]);
    });
    

    【讨论】:

      猜你喜欢
      • 2018-09-23
      • 2017-02-27
      • 2019-11-25
      • 1970-01-01
      • 2016-11-27
      • 2018-03-08
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      相关资源
      最近更新 更多