Angular 2 unit test routerLink click on html element

Viewed 2998

I'm trying to test a component with some links, such as:

<a routerLink="/contact">Contact</a>

Also, I already tried looking into this question, but it didn't solved the problem.

When I try the solution proposed by that question (code below), I keep getting this error

beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [RouterTestingModule],
        declarations: [FooterComponent],
    }).compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(FooterComponent);
    component = fixture.componentInstance;
});

describe('...', () => {
    it('should navigate to "/contact" when clicking on link', async(inject([Location], (location: Location) => {
        fixture.debugElement.query(By.css('.menu')).children[1].nativeElement.click();
        fixture.detectChanges(); 
        fixture.whenStable().then(() => {
            console.log( location.path() );
        });
    })));
});

No provider for Location!

Then, if I tri to set providers: [Location] I get this error:

Failed: StaticInjectorError[LocationStrategy]:
StaticInjectorError[LocationStrategy]:
NullInjectorError: No provider for LocationStrategy!

I tried to spy on the Router, like this:

spyOn(router, 'navigate');
expect(router.navigate).toHaveBeenCalled();

But it fails the test with 'Never called'.

How can I solve this issue?

2 Answers

As pointed by Aluan Haddad in the comments, I was missing the CommonModules on the imports.

After that, the error was gone, but I couldn't make it work. The reason is because I was using a MockModule, where I import all the common services, components, modules, etc.. Used across the tests, including the RouterTestingModule.

Removing the RouterTestingModule from the common MockModule and moving it direct into the imports, solved the issue.

// before
imports: [MockModule],

// after
imports: [RouterTestingModule.withRoutes(routing)],

Since I searched for an answer for some time but couldn't find one, this is for everyone who couldn't resolve the "Expected spy ... but it was never called" issue with the answer above.

The routerLink directive of angular actually routes with 'navigateByUrl' instead of 'navigate', so your spy would have to look like this

spyOn(router, 'navigateByUrl')
Related