Slide 1

Slide 1 text

Angular Unit Testing mit Jest Christian Liebel @christianliebel Consultant

Slide 2

Slide 2 text

The image part with relationship ID rId12 was not found in the file. The image part with relationship ID rId12 was not found in the file. Special Day Modern Business Applications Thema Sprecher Datum, Uhrzeit Web-API mit Turbo: Deep-dive in async/await bei Backend-APIs Sebastian Gingter DI, 21. September 2021, 10.45 bis 11.45 Web Components in modernen Web-Apps: Hype oder Heilsbringer? Peter Kröner DI, 21. September 2021, 12.15 bis 13.15 Produktivitäts-PWAs mit Angular auf Desktopniveau Christian Liebel DI, 21. September 2021, 14.30 bis 15.30 Angular Unit Testing mit Jest Christian Liebel DI, 21. September 2021, 16.00 bis 17.00 SPAs in Azure betreiben - ein Leitfaden aus der Praxis Thorsten Hans MI, 22. September 2021, 17.30 bis 18.30

Slide 3

Slide 3 text

1. Testing Overview 2. Unit Testing Basics 3. Jest vs. Karma/Jasmine 4. Testing with Jest 5. Spies & Mocks 6. E2E Tests Overview Angular Unit Testing mit Jest Agenda

Slide 4

Slide 4 text

Test Types End-to-end Tests (~ 1000 ms, 10%) Acceptance tests simulating a real user Integration Tests (~ 100 ms, 20%) Tests the integration of different modules Unit Tests (~ 10 ms, 70 %) Tests a class, method or algorithm Angular Unit Testing mit Jest Testing Overview

Slide 5

Slide 5 text

Test-Driven Development First, write your test (= requirements!) See it failing Next, write the minimum required implementation to fulfill the test See your test turn green (Refactor) Repeat Angular Unit Testing mit Jest Unit Testing Basics

Slide 6

Slide 6 text

Brownfield Testing Use Extract Method refactoring to… - reduce complexity of large methods (target method length: 7±2 lines) - avoid more than one nesting/indent level Move large blocks of code in own files or services (target file length: ±100 lines) Angular Unit Testing mit Jest Unit Testing Basics

Slide 7

Slide 7 text

A-TRIP Pattern Unit Tests should be… - Automatic (no user interaction required) - Thorough (test critical functionality) - Repeatable (repeated execution leads to same result) - Independent (order does not matter) - Professional (test code doesn’t test itself) Angular Unit Testing mit Jest Unit Testing Basics

Slide 8

Slide 8 text

Unit Testing Support Unit Tests (~ 10 ms, 70 %) Tests a class, method or algorithm Integration Tests (~ 100 ms, 20%) Tests the integration of different modules End-to-end Tests (~ 1000 ms, 10%) Acceptance tests simulating a real user Angular Unit Testing mit Jest Angular

Slide 9

Slide 9 text

Unit Testing Support Angular CLI schematics automatically create a test specification file (*.spec.ts) for each generated unit. Angular Unit Testing mit Jest Angular

Slide 10

Slide 10 text

Angular’s Default Testing System - Does not require additional project configuration - Requires a browser (e.g. Chrome Headless for CI environments) - Tests run sequentially Angular Unit Testing mit Jest Karma & Jasmine

Slide 11

Slide 11 text

Test runner Angular Unit Testing mit Jest Jest - Fast: Tests run in parallel - Easy CI setup: No browser required (JSDom) - Setup: ng add @briebug/jest-schematic - Jasmine BDD testing framework is mostly compatible with Jest - Migration: npx jest-codemods

Slide 12

Slide 12 text

Introduction https://jestjs.io/docs/en/getting-started Angular Unit Testing mit Jest Jest

Slide 13

Slide 13 text

Simple Test describe("A suite is just a function", () => { let a; test("and so is a spec", () => { a = true; expect(a).toBe(true); }); }); Angular Unit Testing mit Jest Jest

Slide 14

Slide 14 text

AAA Pattern Arrange const x = …; Act const result = sut.myTestMethod(x); Assert expect(result).toBeDefined(); Angular Unit Testing mit Jest Unit Tests

Slide 15

Slide 15 text

Matchers expect(123).toBe(123); expect({ foo: 123 }).toEqual({ foo: 123 }); expect([1, 2, 3]).toContain(3); expect(false).toBeFalsy(); expect(1).toBeTruthy(); expect(null).toBeNull(); expect(undefined).toBeUndefined(); expect(999).toBeDefined(); expect(() => method()).toThrow(); Angular Unit Testing mit Jest Jest

Slide 16

Slide 16 text

Suggestion describe('FooService', () => { describe('method', () => { test('should do this', () => {}); test('should do that', () => {}); }); }); - 1 suite per class - 1 suite per method - n tests (use “should” and prevent “and”) Angular Unit Testing mit Jest Jest

Slide 17

Slide 17 text

Setup/Teardown Run before/after each test in this suite beforeEach afterEach Run before/after all tests in this suite beforeAll afterAll Angular Unit Testing mit Jest Jest

Slide 18

Slide 18 text

Excluding/including tests Exclude this test (suite) describe.skip test.skip Only include this test (suite) describe.only test.only Angular Unit Testing mit Jest Jest

Slide 19

Slide 19 text

Test Reminders Remind me to write a test test.todo Angular Unit Testing mit Jest Jest

Slide 20

Slide 20 text

Unit Testing Commands Unit Tests (Karma/Jest) npm test ng test ng t End-to-end Tests ng e2e ng e Angular Unit Testing mit Jest Angular

Slide 21

Slide 21 text

Angular Unit Testing mit Jest DEMO: Testing Angular Pipes

Slide 22

Slide 22 text

Repetitive tests test.each` a | b | expected ${1} | ${1} | ${2} ${1} | ${2} | ${3} ${2} | ${1} | ${3} `('returns $expected when $a is added $b', ({a, b, expected}) => { expect(a + b).toBe(expected); }); Angular Unit Testing mit Jest Jest https://jestjs.io/docs/en/api#testeachtablename-fn-timeout

Slide 23

Slide 23 text

Mock Functions const mock = jest.fn(x => 42 + x); // The mock function is called twice expect(mockCallback.mock.calls.length).toBe(2); // The first argument of the second call to the function was 1 expect(mockCallback.mock.calls[1][0]).toBe(1); Angular Unit Testing mit Jest Jest https://jestjs.io/docs/en/mock-functions

Slide 24

Slide 24 text

Spies jest.spyOn(existingObject, 'existingFunction'); // spyOn also calls the function, alternatives: // jest.spyOn(/* … */).mockImplementation(() => 42); // existingObject['existingFunction'] = jest.fn(() => 42); expect(existingObject.existingFunction).toHaveBeenCalled(); // optional: toHaveBeenCalledWith(arg1, arg2) // optional: toHaveBeenCalledTimes(4) Angular Unit Testing mit Jest Jest

Slide 25

Slide 25 text

Basics // Creating mock let mockedFoo:Foo = mock(Foo); // Getting instance from mock let foo:Foo = instance(mockedFoo); // Using instance in source code foo.getBar(5); // Explicit, readable verification verify(mockedFoo.getBar(5)).called(); Angular Unit Testing mit Jest ts-mockito https://www.npmjs.com/package/ts-mockito

Slide 26

Slide 26 text

Stubbing Method Calls // Creating mock let mockedFoo:Foo = mock(Foo); // stub method before execution when(mockedFoo.getBar(3)).thenReturn('three'); // Getting instance let foo:Foo = instance(mockedFoo); // prints three console.log(foo.getBar(3)); Angular Unit Testing mit Jest ts-mockito https://www.npmjs.com/package/ts-mockito

Slide 27

Slide 27 text

AAA Pattern & Mocks Arrange const x = …; Setup when(mock.myOtherMethod).thenReturn(3); Act const result = sut.myTestMethod(x); Assert expect(result).toBeDefined(); Verify verify(mock.myOtherMethod).called(); Angular Unit Testing mit Jest Unit Tests

Slide 28

Slide 28 text

Angular Unit Testing mit Jest DEMO: Mocking Dependencies

Slide 29

Slide 29 text

Testing Utilities: TestBed describe('Component: Login', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [LoginComponent], providers: [AuthService] }); }); }); Angular Unit Testing mit Jest Angular https://codecraft.tv/courses/angular/unit-testing/angular-test-bed/

Slide 30

Slide 30 text

Angular Unit Testing mit Jest DEMO: Using the TestBed

Slide 31

Slide 31 text

Snapshot Testing test('should create the app', () => { const fixture = TestBed.createComponent(AppComponent); expect(fixture).toMatchSnapshot(); }); Angular Unit Testing mit Jest Jest

Hallo

Hxllo

Slide 32

Slide 32 text

Angular Unit Testing mit Jest DEMO: Snapshot Testing

Slide 33

Slide 33 text

Test Watcher npm test -- --watch npm test -- --watch-all Angular Unit Testing mit Jest Jest

Slide 34

Slide 34 text

Code Coverage npm test -- --coverage Code coverage provided by Istanbul Coverage metadata written to coverage folder Code coverage policy: ~ 80% Angular Unit Testing mit Jest Angular

Slide 35

Slide 35 text

Cypress https://www.cypress.io/ DevExpress TestCafé https://devexpress.github.io/testcafe/ Angular Unit Testing mit Jest E2E Tests

Slide 36

Slide 36 text

Thank you for your kind attention! Christian Liebel @christianliebel [email protected]