Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Angular testing hygiene

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Angular testing hygiene

Avatar for Piotr Lewandowski

Piotr Lewandowski

March 25, 2021
Tweet

More Decks by Piotr Lewandowski

Other Decks in Programming

Transcript

  1. piotrl.net 2 • JavaScript tes-ng is great, but not bullet

    proof • When the app scales, some prac-ces needs to be adjusted Lighiting Talk – 15min 3 #ps for today
  2. piotrl.net 4 What testing modules do we know? • HttpClientTestingModule

    • RouterTestingModule • BrowserTestingModule • NoopAnimationsModule Goal? • Avoid imperative mocking • Deliver predefined mocks and used modules • Cut Dependency Injection tree @NgModule({ providers: [ IconRegistryMock, { provide: IconRegistry, useExisting: IconRegistryMock, }, ], }) export class IconTestingModule { } @Injectable() export class IconRegistryMock { getIcon(name: string): Observable<string> { return of('<svg></svg>'); } }
  3. piotrl.net 6 Configurable testing modules? @NgModule() export class FeatureFlagsTestingModule {

    static with(config) { return { ngModule: FeatureFlagsTestingModule, providers: [ { provide: FeatureFlagsService, useFactory: () => new FeatureFlagsServiceMock(config), }, ], }; } }
  4. piotrl.net 8 What is shallow testing? <dt-smart-code-editor *ngIf="smartEditor"> {{ someCode

    | json }} </dt-smart-code-editor> <pre *ngIf="smartEditor"> {{ someCode | json }} </pre> page-xyz.component.html huge component WHAT IF? Our page have 100 huge components And their children have 100 huge components And so on ... schemas: [NO_ERRORS_SCHEMA],
  5. piotrl.net 9 When? Testing huge components page-xyz.component.spec.ts TestBed.configureTestingModule( { declarations:

    [ ComponentWeTest, MockOfChildComponent1, MockOfChildComponent2, MockOfChildComponent3, // and so on for up to MockOfChildComponent4, // 10, 20 mocked child components MockOfChildComponent5, MockOfChildComponent6, ], imports: [ YourModuleWrappingAllDependenciesForAllModules, ButtonComponentModule, // + other design components DependentModule1, DependentModule2, DependentModule3, DependentModule4, // and so on for up to DependentModule1, // 10, 20 imported modules ], }) EFFECT Single test suite 20s+ Modified shared direc2ve = broken test Dependency mess. Hard to maintain.
  6. piotrl.net 10 Apply shallow testing page-xyz.component.spec.ts TestBed.configureTestingModule({ schemas: [NO_ERRORS_SCHEMA], declarations:

    [ ComponentWeTest, ], imports: [ // only TestingModules // for direct dependencies of ComponentWeTest ], providers: [ // only mocks for direct dependencies of ComponentWeTest // or mocks that we modify for test behaviour ], }); EFFECT Single test suite 200ms Modified shared directive = not affecting test Truly unit test. No maintanance effort Cannot do integra2on tes2ng
  7. 12 When do we deal with asynchronous code in tests?

    • async/await • async functions • waitForAsync() • observables with done() Avoid all in tests: • Race condi-ons • Slow tests because we’re wai-ng for real events • Always green tests if we’re not careful
  8. 13 Async with done() is it really bad? better approach?

    Rx marbles fakeAsync() it('should refresh after 1s', (done) => { // given // when serviceWithTimeout().subscribe((el) { // then expect(el).toBeTruthy(); done(); }); });
  9. 14 RxJs and fakeAsync() it('should be green for async', fakeAsync(()

    => { // given const result = []; // when interval(1000).subscribe((el) => result.push(el)); tick(2000); // then expect(result).toEqual([0, 1]); })); fakeAsync() > waitForAsync() piotrl.net