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

Unit-Testing in Angular mit Jest

Unit-Testing in Angular mit Jest

Unit-Tests sind ein hervorragendes Mittel, um (kritische) Funktionalität einer Anwendung automatisiert und schnell überprüfen zu lassen. Das SPA-Framework Angular liefert mit Karma von vornherein eine Testunterstützung mit. Mit Facebooks Jest gibt es jedoch ein weiteres Framework, das unter anderem mit paralleler Testausführung lockt. In diesem Webinar zeigt Ihnen Christian Liebel, wie Sie Ihre Angular-App mithilfe von Jest testen können. Nachdem wir zu Beginn ein gemeinsames Verständnis zum Thema Unit Tests geschaffen haben, werden wir uns abschließend auch fortgeschrittenen Inhalten wie Spys und Mocks nähern. Melden Sie sich jetzt kostenlos an. Wir freuen uns auf Sie!

Christian Liebel
PRO

June 23, 2021
Tweet

More Decks by Christian Liebel

Other Decks in Programming

Transcript

  1. Angular
    Unit Testing with Jest
    Christian Liebel
    @christianliebel
    Consultant

    View Slide

  2. Angular
    Unit Testing
    DEMO: Motivation

    View Slide

  3. 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
    Agenda O

    View Slide

  4. 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
    Testing Overview

    View Slide

  5. 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
    Unit Testing Basics

    View Slide

  6. 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
    Unit Testing Basics

    View Slide

  7. 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
    Unit Testing Basics

    View Slide

  8. 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
    Angular

    View Slide

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

    View Slide

  10. 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
    Karma & Jasmine

    View Slide

  11. Test runner
    Angular
    Unit Testing
    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
    P

    View Slide

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

    View Slide

  13. 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
    Jest

    View Slide

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

    View Slide

  15. 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
    Jest

    View Slide

  16. 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
    Jest

    View Slide

  17. 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
    Jest

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  21. Angular
    Unit Testing
    DEMO: Testing Angular Pipes

    View Slide

  22. 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
    Jest
    https://jestjs.io/docs/en/api#testeachtablename-fn-timeout

    View Slide

  23. 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
    Jest
    https://jestjs.io/docs/en/mock-functions

    View Slide

  24. 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
    Jest

    View Slide

  25. 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
    ts-mockito
    https://www.npmjs.com/package/ts-mockito

    View Slide

  26. 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
    ts-mockito
    https://www.npmjs.com/package/ts-mockito

    View Slide

  27. 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
    Unit Tests

    View Slide

  28. Angular
    Unit Testing
    DEMO: Mocking Dependencies O

    View Slide

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

    View Slide

  30. Angular
    Unit Testing
    DEMO: Using the TestBed

    View Slide

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

    View Slide

  32. Angular
    Unit Testing
    DEMO: Snapshot Testing

    View Slide

  33. Test Harnesses
    test('should mark confirmed when ok button clicked', async () => {
    const okButton = await loader.getHarness(MatButtonHarness.with({selector:
    '.confirm'});
    expect(fixture.componentInstance.confirmed).toBe(false);
    expect(await okButton.isDisabled()).toBe(false);
    await okButton.click();
    expect(fixture.componentInstance.confirmed).toBe(true);
    });
    https://material.angular.io/guide/using-component-harnesses
    Angular
    Unit Testing
    Angular

    View Slide

  34. Testing Utilities: fakeAsync
    describe('this test', () => {
    test('looks async but is synchronous', fakeAsync((): void => {
    let flag = false;
    setTimeout(() => { flag = true; }, 100);
    expect(flag).toBe(false);
    tick(50);
    expect(flag).toBe(false);
    tick(50);
    expect(flag).toBe(true);
    }));
    });
    Angular
    Unit Testing
    Angular
    https://angular.io/api/core/testing/fakeAsync

    View Slide

  35. Testing Utilities: HttpTestingController
    https://www.techiediaries.com/angular-testing-httptestingcontroller/
    Angular
    Unit Testing
    Angular

    View Slide

  36. Test Watcher
    npm test -- --watch
    npm test -- --watch-all
    Angular
    Unit Testing
    Jest

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide