4

This is my method in the component.

 editThis(id) {
    this.router.navigate(['/categories/edit'], { queryParams: { id: id } });
  }

This is my unit test-case.

fit('should call navigate with correct params', () => {
    component.editThis("5c7d5fde213e25232864dbe0");
    expect(new MockRouter().navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });
  });

This is the mocked router.

class MockRouter {
  navigateByUrl(url: string) { return url; }
  navigate = jasmine.createSpy('navigate');

}

I am getting this error.

Expected spy navigate to have been called with [ [ '/categories/edit' ], Object({ queryParams: Object({ id: '5c7d5fde213e25232864dbe0' }) }) ] but it was never called.

Can you suggest me a way to test the method?

Full test code.

import { FacadeService } from './../../../services/facade.service';
import { HttpClientModule } from '@angular/common/http';
import { AngularFontAwesomeModule } from 'angular-font-awesome';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { CategoriesViewComponent } from './categories-view.component';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable, of } from 'rxjs';
import { Router } from '@angular/router';

var allCategories = [

  {
    "_id": "5c7d5fde213e25232864dbe0",
    "name": "Politics",
    "updatedAt": "2019-03-04T17:26:54.262Z",
    "createdAt": "2019-03-04T17:26:54.262Z",
    "__v": 0
  }
];

class MockRouter {
  navigateByUrl(url: string) { return url; }
  navigate = jasmine.createSpy('navigate');

}

class MockedFacadeService {
  getUserDataFromLocalStorage() {
    return false;
  }
  getGuestPermissionsFromLocalStorage() {
    return { "comments": { "create": false, "read": true, "update": false, "deleteAny": false, "delete": false }, "post": { "create": false, "read": true, "update": false, "delete": false, "like": false, "dislike": false }, "category": { "create": false, "read": true, "update": false, "delete": false } };
  }
  getCategories() {
    return of(allCategories);
  }
}

describe('CategoriesViewComponent', () => {
  let component: CategoriesViewComponent;
  let fixture: ComponentFixture<CategoriesViewComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [AngularFontAwesomeModule, RouterTestingModule, HttpClientModule],
      declarations: [CategoriesViewComponent],
      providers: [{ provide: FacadeService, useClass: MockedFacadeService },
      { provide: Router, useClass: MockRouter }]
    })
      .compileComponents();
  }));

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

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

  fit('should call navigate with correct params', () => {
    component.editThis("5c7d5fde213e25232864dbe0");
    expect(new MockRouter().navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });
  });

});
5
  • Could you provide the full test configuration? Commented Mar 7, 2019 at 10:59
  • There is no way that your code under test could possibly call a method on the new object new MockRouter() that you create in the test. It calls this method on a different object. You need to inject a mock router in the component under test, then run your code, then test that the injected mock router has been called. Or you need to get a reference to the actual router used by the component, spy on it, run the code, and then verify that the spied methods have been called. Commented Mar 7, 2019 at 11:01
  • Of course that expect will always fail, you are instantiating a new mock router on it... Commented Mar 7, 2019 at 11:02
  • see codecraft.tv/courses/angular/unit-testing/routing Commented Mar 7, 2019 at 11:05
  • Uploaded the whole test file. Commented Mar 7, 2019 at 11:17

2 Answers 2

5

Change your line:

expect(new MockRouter().navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });

to the following:

expect(TestBed.get(Router).navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });

This will get the actual router object that was instantiated in the TestBed.

I hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

-1

The router already has a mock that you may use.

https://angular.io/api/router/testing/RouterTestingModule

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.