【问题标题】:Angular: Unit Testing Routing : Expected '' to be '/route'Angular:单元测试路由:预期 '' 是 '/route'
【发布时间】:2018-01-15 19:14:09
【问题描述】:

我正在为我的 Angular 应用程序下的路由进行单元测试,

我的路线在 app.module.ts 下导入的特定模块中声明,

这是我的路由模块:

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { LoginComponent } from './login/login.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { CustomersListComponent } from './customer/customers-list/customers-list.component';
import { CustomerDetailComponent } from './customer/customer-detail/customer-detail.component';
import { ApplicationParametersComponent } from './superAdministrator/application-parameters/application-parameters.component';
import { InscriptionComponent } from './inscription/inscription.component';

const routes: Routes = [
  { path: '', redirectTo: '/login', pathMatch: 'full' },
  { path: 'login',  component: LoginComponent },
  { path: 'login/:keyWording',  component: LoginComponent },
  { path: 'welcome', component: WelcomeComponent },
  { path: 'customers-list', component: CustomersListComponent },
  { path: 'customer-create', component: CustomerDetailComponent },
  { path: 'customer-detail/:idCustomer', component: CustomerDetailComponent },
  { path: 'application-parameters', component: ApplicationParametersComponent },
  { path: 'inscription', component: InscriptionComponent }
];

@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule {}

这是我的 app.module.ts (用于导入路由模块的地方:

import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { SharedModule } from './../shared/shared.module';
import { LoginComponent } from './login/login.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { AppComponent } from './app.component';
import { CustomerModule } from './customer/customer.module';
import { ApplicationParametersComponent } from './superAdministrator/application-parameters/application-parameters.component';
import { InscriptionComponent } from './inscription/inscription.component';

import { DxProgressBarModule } from 'devextreme-angular';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    WelcomeComponent,
    ApplicationParametersComponent,
    InscriptionComponent
  ],
  imports: [
    AppRoutingModule, /* HERE IS THE ROUTING FILE */

    SharedModule,
    CustomerModule,
    DxProgressBarModule/*,
    BrowserAnimationsModule,
    BrowserModule*/
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

在我的测试文件下,我遵循了这个博客中的教程: https://codecraft.tv/courses/angular/unit-testing/routing/

我的路由测试文件如下:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
// DevExtreme Module
import {DxProgressBarModule, DxTemplateModule} from 'devextreme-angular';
// Router Modules
import {RouterTestingModule} from '@angular/router/testing';
// Services and HTTP Module
import { SessionService } from './../shared/service';
import { HttpService } from './../shared/service';
import {HttpModule} from '@angular/http';
// Routs testing
import {Router, RouterModule} from '@angular/router';
import {fakeAsync, tick} from '@angular/core/testing';
import {Location} from '@angular/common';
import {LoginComponent} from './login/login.component';
import {WelcomeComponent} from './welcome/welcome.component';
import {ApplicationParametersComponent} from './superAdministrator/application-parameters/application-parameters.component';
import {InscriptionComponent} from './inscription/inscription.component';
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {FormsModule} from '@angular/forms';


describe('Testing the application routes', () => {

  let location: Location;
  let router: Router;
  let fixture;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule, FormsModule , DxTemplateModule , HttpModule ],
      providers:    [SessionService , HttpService ],
      declarations: [
        AppComponent,
        LoginComponent,
        WelcomeComponent,
        ApplicationParametersComponent,
        InscriptionComponent
      ],
      schemas: [ CUSTOM_ELEMENTS_SCHEMA ]

    });

    router = TestBed.get(Router);
    location = TestBed.get(Location);

    fixture = TestBed.createComponent(AppComponent);
    router.initialNavigation();
  });

  it('navigate to "inscription" takes you to /inscription', fakeAsync(() => {
    router.navigate(['inscription']);
    tick();
    expect(location.path()).toBe('/inscription');
  }));
});

我的测试失败了,表明这一点:

Expected '' to be '/inscription'.
    at Object.<anonymous> (webpack:///src/app/app-routing.spec.ts:52:28 <- src/test.ts:143891:33)
    at Object.<anonymous> (webpack:///~/@angular/core/@angular/core/testing.es5.js:348:0 <- src/test.ts:34691:26)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:391:0 <- src/polyfills.ts:1546:26)
    at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:232357:39)

想法??

【问题讨论】:

  • 可以添加AppRoutingModule的内容吗?问题似乎来自其中的错误配置。
  • @Supamiu O.o 它已经共享 -> 第一个文件:app-routing..module.ts
  • 没关系,我好像有眼虫了。

标签: angular unit-testing typescript routing karma-jasmine


【解决方案1】:

您忘记在测试文件中将路由导入RouterTestingModule

您必须在您的AppRoutingModule 文件中将export 关键字添加到您的const routes,然后您可以在您的测试文件中import 路由(并将它们添加到您的测试配置中)。

import {routes} from '...'; // I don't have the app-routing.module file path.
...
...
...
 beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule.withRoutes(routes), <-- I added the routes here.
                FormsModule , DxTemplateModule , HttpModule 
  ],
      providers:    [SessionService , HttpService ],
      declarations: [
        AppComponent,
        LoginComponent,
        WelcomeComponent,
        ApplicationParametersComponent,
        InscriptionComponent
      ],
      schemas: [ CUSTOM_ELEMENTS_SCHEMA ]

    });

    router = TestBed.get(Router);
    location = TestBed.get(Location);

    fixture = TestBed.createComponent(AppComponent);
    router.initialNavigation();
  });

如果你在路由器测试模块中不加载路由,当你navigate时它将无法知道去哪里,所以它会回到原来的页面并在控制台出错。

您遵循的教程有一种非常奇怪的路由处理方式,因为tick() 用于fakeAsync 测试,这是一个真正的async 测试。所以你必须使用router.navigate返回的Promise&lt;boolean&gt;

it('navigate to "inscription" takes you to /inscription', () => {
    router.navigate(['inscription']).then(() => {
        expect(location.path()).toBe('/inscription');
    });
});

如您所见,您也可以删除fakeAsync,因为这不是假的,而是async 调用。

See it on plunkr

【讨论】:

  • 我做到了,但仍然失败:ERROR src/app/app-routing.module"' has no export member 'routes
  • 您必须在src/app/app-routing.module 中将export 添加到const routes,正如我在答案开头所说的那样;)
  • 仍然是同样的错误预期 '' 是 '/inscription'。在 Object. (webpack:///src/app/app-routing.spec.ts:60:28 (webpack:// /~/@angular/core/@angular/core/testing.es5.js:348:0
  • 尝试将tick() 更改为tick(50),让路由器有更多时间正确导航。
  • 即使在 tuto plunkr 中,也会出现同样的错误:plnkr.co/edit/mTYEDNRlgGjdwv3M5b28?p=preview
猜你喜欢
  • 2022-06-23
  • 2017-12-20
  • 1970-01-01
  • 2013-04-06
  • 2020-08-15
  • 2013-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多