How to write unit tests for Angular Flex-layout directives (fxHide, fxShow)?

733 Views Asked by At

I think that the Angular Flex-Layout library is great, but I couldn't figure out how to test its directives like fxHide or fxShow For example, if you have a template like that:

<div fxHide.lt-md class="my-div">Should not be visible for small devices (xs, sm)</div>

How should you mock the screen size values to test it?

1

There are 1 best solutions below

0
On

So I've found the answer inside the @angular/flex-layout internal unit tests here.

To mock the values you have to inject a mocked version of MatchMedia like this:

import {
  FlexLayoutModule,
  ɵMatchMedia as MatchMedia,
  ɵMockMatchMedia as MockMatchMedia,
} from '@angular/flex-layout';

describe('template tests', () => {
  let mediaController: MockMatchMedia;

  let fixture: ComponentFixture<MyComponent>;
  let component: MyComponent;
  let el: DebugElement;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [FlexLayoutModule],
        providers: [{ provide: MatchMedia, useClass: MockMatchMedia }],
        declarations: [MyComponent],
      })
        .compileComponents()
        .then(() => {
          fixture = TestBed.createComponent(MyComponent);

          inject([MatchMedia], (_matchMedia: MockMatchMedia) => {
            mediaController = _matchMedia;
          })();

          component = fixture.componentInstance;
          el = fixture.debugElement;
        });
    }),
  );

  afterEach(() => {
    mediaController.clearAll();
  });

  it('should not display day of week for mobile', () => {
    mediaController.activate('lt-md');
    fixture.detectChanges();
    const divDbEl = el.query(By.css('.my-div'));
    expect(divDbEl).toBeTruthy();
    expect(divDbEl.styles.display).toEqual('none'); // Should be hidden
  });
});

So, you need:

  1. Import mocks from @angular/flex-layout/core: import { ɵMatchMedia as MatchMedia, ɵMockMatchMedia as MockMatchMedia } from '@angular/flex-layout/core';
  2. Declare let mediaController: MockMatchMedia;
  3. Inside beforeEach configure the testing module:
imports: [FlexLayoutModule],
providers: [{ provide: MatchMedia, useClass: MockMatchMedia }]
  1. After you compile the component, inject the mocked version of MatchMedia:
inject([MatchMedia], (_matchMedia: MockMatchMedia) => {
        mediaController = _matchMedia;
})();
  1. Inside afterEach you can reset some values:
    afterEach(() => {
        mediaController.clearAll();
    });
  1. Activate the screen size you need: mediaController.activate('lt-md');
  2. Test the display style is set to 'none': expect(divDbEl.styles['display']).toEqual('none');