0

I have below code in my constructor

  constructor(
    private ngxSpinner: NgxSpinnerService,
    private userSecurityService: UserSecurityService,
    private userInformationService: UserInformationService,
    private navigateService: NavigateService,
    private titleService: Title,
    private router: Router
  ) {
    this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: NavigationEnd) => {
      this.currentPath = event.url;
      if(this.currentPath.indexOf('/custom-fields?view=edit') > -1) {
        this.isCustomfieldsPage = true;
      } else {
        this.isCustomfieldsPage = false;
      }
    });
  }

And below are my test cases

  it('check if isCustomfieldsPage is true', () => {
    spectator.component.isCustomfieldsPage = true;
    spectator.component.currentPath = 'https://csc.com/admin/custom-fields?view=edit';
    expect(spectator.component.isCustomfieldsPage).toBe(true);
  }); 

  it('check if isCustomfieldsPage is false', () => {
    spectator.component.isCustomfieldsPage = false;
    spectator.component.currentPath = 'https://csc.com/admin/manage-fields';
    expect(spectator.component.isCustomfieldsPage).toBe(false);
  });

The above test cases are not covering the code which is inside the constructor? How can I modify my code to work as expected. Please suggest. Thanks.

vamsi
  • 1,488
  • 3
  • 28
  • 66
  • Why do you want to test particular code? Usually we are testing the expected behavior but not the implementation. And as far as I can see you are doing well. Did I missed something? – Drag13 Nov 30 '21 at 09:45
  • The problem is code coverage, we have a rule to cover atleast 85% code we write.. Sad, but true. – vamsi Nov 30 '21 at 09:48
  • We use a tool called Sonar to check the code coverage, in that report we see that code is not being covered by my test cases. – vamsi Nov 30 '21 at 09:49
  • I see the reason. I would try two options: Move the code to ` ngOnInit` method and call it from the test. The second option - double check the report generator, might be you can find those who calculates constructors correctly – Drag13 Nov 30 '21 at 09:54
  • But I worked with Sonar and didn't mention such issue with him – Drag13 Nov 30 '21 at 09:55

1 Answers1

0

This is a bit generic without looking up existing tests, but yes you can do this:

const router: Router
const myComponent: Mycomponent
const routerEventsObserver;
beforeEach(() => {
  // set up test bed 
})
beforeEach(() => {
  router = TestBed.inject(Router);
  router.events = new Observable((observer) => { 
   routerEventsObserver = observer
  });
  myComponent = TestBed.createComponent(MyComponent);
})

The order is important here. You're getting an instance of the router and replacing the internal events observable with one that you have manually created, and doing so before the component is created. When the component is created, your modified router.events observable is the one that is listened to.

now write your tests:

it('should do something', () => {
  // create mock result object representing NavigationEnd
  routerEventsObserver.next(My mock result object);
  // assertions 
})

Edit to say: Even if you move the code to ngOnInit() and manually call it, as suggested in the comments, I'd still use an approach similar to this; mocking the Observable in the service, getting reference to the internal observer. and controlling when it the subscribe function runs

JeffryHouser
  • 39,401
  • 4
  • 38
  • 59