Tuesday, 14 May 2019

Intermittent error cannot match any routes unit testing Angular

I've read many posts on the subject about using the router testing module and trying to spy on the router.navigate method but none have resolved the issue I have. Every 2nd run of my tests or so I will see the error, here's the first line in full

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

To reiterate the error has not been seen when I run my app only when testing

It only appears once no matter how many tests are in the component and it's always the first test that it happens for, if I switch the order then it's the new first test that fails with this error

My component is as follows ( unrelated code removed for brevity )

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);
        }
      );
  }
}

Here's the spec, again unrelated tests removed

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();
  });

I have also tried spying on the router as below (rest of code unchanged)

  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);
  }));

and I have tried injecting my own mock for navigate as below

  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();
  }));



from Intermittent error cannot match any routes unit testing Angular

No comments:

Post a Comment