间歇性错误无法匹配任何路由单元测试Angular

Intermittent error cannot match any routes unit testing Angular

我读过很多关于使用路由器测试模块并试图监视 router.navigate 方法的帖子,但 none 已经解决了我遇到的问题。我的测试每 2 次 运行 左右就会看到错误,这是完整的第一行

Uncaught Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'post/view'

重申一下,当我 运行 我的应用程序仅在测试时

时没有看到错误

无论组件中有多少测试,它只出现一次,它始终是第一个测试,如果我切换顺序,那么它是新的第一个测试失败并出现此错误

我的组件如下(为简洁起见删除了无关代码)

export class CreatePostComponent implements OnInit {

  constructor(private postService: PostService,
              private router: Router,
              private location: Location) {
  }

  submitPost() {
    this.validMessage = '';
    if (!this.createPostForm.valid) {
      this.validMessage = 'Please fill out the form before submitting!';
      return;
    }
    const post = this.createPostForm.value as IPost;
    this.postService.createPost(post)
      .pipe(first())
      .subscribe(
        data => {
          this.createPostForm.reset();

          //Here's the call that I believe causes the issues
          this.router.navigate(['post/view']);
        },
        error => {
          return throwError(error);
        }
      );
  }
}

这是规范,再次删除了不相关的测试

describe('CreatePostComponent', () => {
  let component: CreatePostComponent;
  let fixture: ComponentFixture<CreatePostComponent>;
  let http: HttpTestingController;
  let mockPostService;
  let mockLocationService;


  beforeEach(async(() => {
    mockPostService = jasmine.createSpyObj(['createPost']);
    mockLocationService = jasmine.createSpyObj(['back']);
    TestBed.configureTestingModule({
      declarations: [CreatePostComponent],
      imports: [ReactiveFormsModule,
        HttpClientTestingModule,
        RouterTestingModule],
      providers: [
        {provide: PostService, useValue: mockPostService},
        {provide: Location, useValue: mockLocationService}]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    http = TestBed.get(HttpTestingController);
    fixture = TestBed.createComponent(CreatePostComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

我也试过如下监视路由器(其余代码不变)

  beforeEach(async(() => {
    mockPostService = jasmine.createSpyObj(['createPost']);
    mockLocationService = jasmine.createSpyObj(['back']);
    TestBed.configureTestingModule({
      declarations: [CreatePostComponent],
      imports: [ReactiveFormsModule,
        HttpClientTestingModule,
        RouterTestingModule],
      providers: [
        {provide: PostService, useValue: mockPostService},
        {provide: Location, useValue: mockLocationService}]
    })
      .compileComponents();

    spyOn<any>(component['router'], 'navigate').and.returnValue(true);
  }));

并且我已经尝试注入我自己的 mock 以进行导航,如下所示

  beforeEach(async(() => {
    mockPostService = jasmine.createSpyObj(['createPost']);
    mockLocationService = jasmine.createSpyObj(['back']);
    TestBed.configureTestingModule({
      declarations: [CreatePostComponent],
      imports: [ReactiveFormsModule,
        HttpClientTestingModule],
      providers: [
        {provide: PostService, useValue: mockPostService},
        {provide: Location, useValue: mockLocationService},
        {provide: Router, useValue: {navigate: () => true}}]
    })
      .compileComponents();
  }));

您没有为 RouterTestingModule 提供任何有效路由,所以它告诉您它不知道如何路由到 'post/view'。将 RouterTestingModule 的导入更改为类似以下内容:

RouterTestingModule.withRoutes([
  { path: 'post/view', component: BlankComponent },
])

其中 BlankComponent 是仅用于测试目的的空组件。

这是一个显示此解决方案的有效 StackBlitz。要重现您的错误,只需注释掉我更改的 RouterTestingModule 声明,并在 Stackblitz 中取消注释掉其下方没有路由的原始声明。

我同意文档在这方面不是很好 - 主要测试文档只是说明将来会有一个文档更详细地描述 RouterTestingModule。请参阅 API 信息 here,它在使用 withRoutes 的末尾给出了一个示例。

希望对您有所帮助。 :)