Search code examples
angulartypescriptjasmine

Angular unit test conditional in constructor


I have an angular component with a conditional in the constructor:

export class NavbarComponent implements OnInit {
  noOpener = true;
  scrumTimerWindow = null;
  jiraTimerWindow = null;
  private windowProps = 'resizable=no,scrollbars,status,top=0,right=0,width=';
  private popupWidth = 360;
  constructor(
    public nav: NavbarService
    ) {
    const hasOpener = window.opener;
    let openerMessage = '';
    try {
      if (hasOpener) {
        this.noOpener = false;
        openerMessage = 'Not Displaying popout link. already popped out';
        this.nav.hide();
      } else {
        this.noOpener = true;
        openerMessage = 'Displaying pop out link';
      }
    } catch (e) {
      console.error(e);
      openerMessage = 'Not Displaying popout link. Already popped out (exception)';
      this.noOpener = false;
      this.nav.hide();
    }
    console.info(openerMessage);
  }

Basically the conditional is looking at the window.opener attribute to see if it has been opened by another page, and based on that shows the menu or not.

I am in doubt as to how I can test it.

I started writing a case:

it('should hide popout link when opened by script',() => {
  const windowSpy = spyOn(window, 'open').and.returnValue(isOpenedMock);
  //...
});

But I realized that I was committing two mistakes:

  1. I would not be able to attach the spy that late.
  2. I would not be able to run the regular tests if the injection succeeds.

So how do I test for both cases? Should I be testing from another component calling it, and if so how? Or should I create an additional NavBar2.component.spec.ts file with the tests with the window.opener cases?


Solution

  • I would do the following.

    describe('NavbarComponent', () => {
      // set up of test, make sure you don't call TestBed.createComponent()
      // because that's when the constructor is called.
    
      describe('with opener', () => {
        beforeEach(() => {
          // set opener to something
          window.opener = {} as any;
          fixture = TestBed.createComponent(NavbarComponent);
          component = fixture.componentInstance;
        });
        
        afterEach(() => {
          // reset the opener property to undefined so it's not set for other 
          // tests
          window.opener = undefined as any;
        });
        
        it('should do xyz', () => {
        
        });    
      });
    
      describe('with no opener', () => {
       // I assume no changes are require here
        beforeEach(() => {
          fixture = TestBed.createComponent(NavbarComponent);
          component = fixture.componentInstance;
        });
        it('should do xyz', () => {
         
        });
      });
    });