George Edwards
George Edwards

Reputation: 9229

Jasmine route spy - undefined is not an object (evaluating 'navigate.calls.mostRecent().args')

I am trying to unit test an angular2 component which uses routeing. I have:

class MockRouter {
}

class MockAuth {
  isLoggedIn(){
    return false;
  }
}

describe('Home', () => {
  beforeEach(() => TestBed.configureTestingModule({
    providers: [
      BaseRequestOptions,
      { provide: Router, useClass: MockRouter },
      HomeComponent,
      { provide: AuthenticationService, useClass: MockAuth }
    ]
  }));

  it('should navigate to login', inject([HomeComponent], (home: HomeComponent) => {
    let navigate = jasmine.createSpy('navigate');
    expect(navigate.calls.mostRecent().args[0]).toEqual(['/login']);
  }));
});

but I am getting error:

TypeError: undefined is not an object (evaluating 'navigate.calls.mostRecent().args') in config/spec-bundle.js (line 41757)

I think that jasmine spy is the right approach, but I have missed something -What am I doing wrong?

Upvotes: 2

Views: 1574

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 208944

You should add the spy into the MockRouter class. So that the spy is spying on the navigate calls in the Router

class MockRouter {
  navigate = jasmine.createSpy('navigate');
}

describe('Home', () => {
  let mockRouter;
  let fixture;
  let component: HomeComponent;

  beforeEach(() => {
     mockRouter = new MockRouter();
     TestBed.configureTestingModule({
        declarations: [ HomeComponent ]
        providers: [
          BaseRequestOptions,
          { provide: Router, useValue: mockRouter },
          { provide: AuthenticationService, useClass: MockAuth }
        ]
      });
      fixture = TestBed.createComponent(HomeComponent);
      component = fixture.createComponent;
  });

  it('should navigate to login', () => {
    // calls component.ngOnInit
    fixture.detectChanges();

    // assuming some navigation has been done
    expect(mockRouter.navigate).toHaveBeenCalledWith(['/login']);
  });
});

Notice:

  • HomeComponent is in declarations, not in providers
  • We hold a reference to the mock in the test, and use useValue instead of useClass when we configure it

Upvotes: 2

Related Questions