如何在Angular 2中测试解析路线?

时间:2016-10-25 07:48:37

标签: angular unit-testing selenium karma-runner

我正在尝试测试订阅路由器事件的简单组件,而我不知道如何模拟代码的那部分。错误如下:无法读取未定义的属性“pairwise”。

  

无法读取未定义

的属性'pairwise'

这是我的测试:

describe('AppComponent', function () {
    let fixture: ComponentFixture<AppComponent>;
    var tendersServiceStub = {};
    var scrollServiceStub = {};
    var routerStub = {};

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [AppComponent],
            providers: [
                {provide: TendersService, useValue: tendersServiceStub},
                {provide: ScrollService, useValue: scrollServiceStub},
                {provide: Router, useValue: routerStub}
            ],
            imports: [RouterTestingModule],
            schemas: [NO_ERRORS_SCHEMA]
        }).compileComponents().then(() => {
            fixture = TestBed.createComponent(AppComponent);
            fixture.detectChanges()
        });
    }));

    it('should instantiate component', () => {
        // console.log(fixture); UNDEFINED
    });
});

这是组件:

export class AppComponent {
    appTitle: string = 'Magic';

    constructor(private router: Router, private tendersService: TendersService, private scrollService: ScrollService) {
        this.router.events.pairwise().subscribe((e) => {
            if ((e[0] instanceof NavigationEnd) && (e[1] instanceof NavigationStart)) {
                this.resetSearchCache(e);
            }
        })
    }

    private resetSearchCache(e: any) {
        if ((e[1].url == '/home') || (e[1].url == '/advancedSearch')) {
            if (!e[0].url.includes('/detail')) {
                //DO SOMETHING
            }
        }
    }

}

有什么想法吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您只需添加events属性,并将值设为Observable即可发出事件数组。

import 'rxjs/add/observable/of';

let mockRouter = {
                          // see notes below. this may be incorrect
  events: Observable.of([ new NavigationStart(1, '/'),
                          new NavigationEnd(1, '/', '/home')])
};

另请参阅NavigationEndNavigationStartRoutesRecognized的文档。根据我的测试,数组实际上在开始事件中包含[NavigationStart, RoutesRecognized],在结束事件上包含[RoutesRecognized, NavigationEnd]。所以你的逻辑可能不正确。

另一种选择是使用真实路由。有时这可能是有益的,而且设置起来并不那么困难。例如,在您的情况下,您可以在home路由转到的测试中添加一个虚拟组件。然后使用RouterTestingModule.withRoutes

配置路由
@Component({
  template: `
  `
})
class HomeComponent {}

describe('WelcomeComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let component: AppComponent;
  let router: Router;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ RouterTestingModule.withRoutes([
        { path: '', redirectTo: 'home', pathMatch: 'full' },
        { path: 'home', component: HomeComponent }
      ])],
      declarations: [ AppComponent, HomeComponent ],
    });
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    router.initialNavigation();
  });
});

这样,第一个路线事件将被触发。此外,如果您愿意,还可以通过导航到其他地方,使用Router手动触发其他事件。