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

Angular testing hygiene

Angular testing hygiene

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