Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2/Jasmine Expect to be null make browser crash

I'm having some trouble with testing one of my components. The test is as follow :

describe('SmpEventsNewCompactEventComponent', () => {

  const specService: SmpSpecService = new SmpSpecService();

  describe('Component rendering', () => {
    let componentInstance: any;
    let componentFixture: ComponentFixture<any>;
    let cssSelector: string;

    beforeEach(() => {
      TestBed.configureTestingModule({
        imports: [
          MaterialModule.forRoot()
        ],
        declarations: [
          SmpEventsCompactEventComponent,
          SmpEventsAddressComponent
        ],
        providers: [
          { provide: SMP_OT_HELPER, useValue: newOtHelperInstance() },
          DatePipe,
          SmpEventTypeCheckerService,
          SmpLangService
        ]
      });

      componentFixture = TestBed.createComponent(SmpEventsCompactEventComponent);
      componentInstance = componentFixture.componentInstance;
    });

    describe('Global', () => {
      it('GIVEN there are date/time AND address ' +
        'WHEN component loads THEN display event', () => {
          //// TEST ONE
          componentInstance.isEventEnabled = true;
          cssSelector = '.events-compact-event';

          let debugElement = specService.queryDebugElement(
            componentFixture, cssSelector);

          expect(debugElement).not.toBeNull();
        });

      it('GIVEN there are no date/time AND no address ' +
        'WHEN component loads THEN do not display event', () => {
          //// TEST TWO
          componentInstance.isEventEnabled = true;
          //componentInstance.isAddressEnabled = false;
          // componentInstance.isDateEnabled = false;
          cssSelector = '.events-compact-event';

          let debugElement = specService.queryDebugElement(
            componentFixture, cssSelector);

            console.log('--------------', debugElement.nativeElement);
          // expect(debugElement.nativeElement).toBe(null);
          // expect(true).toBe(true);
          expect(debugElement).not.toBeNull();
        });
    });
});

The specService.queryDebugElement is as follow :

  queryDebugElement(fixture: ComponentFixture<any>, cssSelector: string): DebugElement {
    fixture.detectChanges();

    return fixture.debugElement.query(By.css(cssSelector));
  }

Whenever i use the

expect(true).toBe(true);

or

expect(debugElement.nativeElement).toBe(null);

or

expect(debugElement).not.toBeNull();

in the TEST TWO, the tests works or fail normally BUT whenever i use

expect(debugElement).toBeNull();

The browser used by karma crash (tested with chrome/chromium/PhantomJs) and does not give any clue of what happens. This is a not a simple "expect false to be true" fail, the test context completly crash.

Do you see anything that could explain this behaviour ?

like image 234
Shireilia Avatar asked Dec 15 '22 01:12

Shireilia


1 Answers

Angular's DebugElement is a rather complex Object, and Jasmine's expect seems to be containing recursive parts (or at least algorithms that are complex enough to need many different function calls)... hence the use of DebugElement directly in unit tests not being recommended. It usually ends in deep recursion and memory leaks from browser.

In your case, I would try :

let nl: NodeList = componentFixture.nativeElement.querySelectorAll('.events-compact-event');

expect(nl.length).toBeFalsy;

This way, you're not using DebugElement, and you're not at risk of having undefined values in your tests (apart from the ones you do need to be undefined). Code coverage and results should be equivalent.

Have a look at this article: https://medium.com/@martatatiana/poor-detective-angular2-browser-crash-and-debugelement-f0a651dbf33

like image 107
Rom Avatar answered Dec 20 '22 20:12

Rom