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

Jest can do whaaat?

Robin Pokorny
November 01, 2017

Jest can do whaaat?

Jest is React’s best testing companion. It also brought several concepts to mainstream JavaScript testing: zero configuration, first-class mocking, and snapshots. With the rapid release of speed improvements, it’s easy to miss a new useful feature. I will present some lesser-known possibilities of recent Jest versions I’ve learned during experimenting, reading (and writing) the docs, and browsing the code.

Code: https://github.com/robinpokorny/jest-can-do-whaaat

Presented at React Open Source: https://www.meetup.com/preview/React-Open-Source/events/244027983

Resources:
- Example code: https://github.com/robinpokorny/jest-can-do-whaaat
- Jest Snapshots and Beyond (https://youtu.be/HAuXJVI_bUs) by Rogelio Guzman (recording)
- Writing snapshot plugins (https://github.com/facebook/jest/tree/master/packages/pretty-format#writing-plugins) in the docs
- Effective Snapshot Testing (https://blog.kentcdodds.com/effective-snapshot-testing-e0d1a2c28eca) by Kent C. Dodds
- Async testing in Jest (https://www.youtube.com/watch?v=bw10S2BK-5w) (recording)
- Snapshot testing in Jest (https://www.youtube.com/watch?v=yUlfFMhVfZo) (recording)
- Async testing Koa with Jest (https://hackernoon.com/async-testing-koa-with-jest-1b6e84521b71)

Robin Pokorny

November 01, 2017
Tweet

More Decks by Robin Pokorny

Other Decks in Technology

Transcript

  1. JEST can do whaaat? React Open Source Berlin 1 November

    2017 @robinpokorny Slides accompany a talk. Here, the talk is missing. For the full experience
 see the recording. I welcome any feedback! INFO
  2. WHAT IS JEST delightful, zero configuration testing platform Jasmine’s and

    Expect’s successor practical utilities for awesome DX http:/ /facebook.github.io/jest/
  3. TEST describe('method', () => { test('works', () => { const

    full = { number: 1975, bool: true, string: 'Hello, Vanek', promise: Promise.resolve('Better job'), symbol: Symbol('brewery'), [Symbol.for(‘brewmaster')]: 'Next beer!', … }; expect(full).toMatchSnapshot(); expect(1936).toMatchSnapshot(); }); });
  4. SNAPSHOT // Jest Snapshot v1, https: //goo.gl/fbAQLP exports[`method works 1`]

    = ` Object { "bool": true, … "undefined": undefined, Symbol(brewmaster): "Next beer!", } `; exports[`method works 2`] = `1936`;
  5. SNAPSHOT ` Object { "bool": true, "func": [Function], "map": Map

    { "position1" => "workman", "position2" => "stockkeeper", }, "null": null, "number": 1975, "promise": Promise {},
  6. SNAPSHOT "set": Set { "think", "write", "snitch", }, "string": "Hello,

    Vanek", "symbol": Symbol(brewery), "undefined": undefined, Symbol(brewmaster): "Next beer!", } `
  7. TEST describe('method', () => { test('works', () => { const

    full = { … }; expect(full).toMatchSnapshot('new name'); }); }); SNAPSHOT exports[`new name 1`] = `…`
  8. TEST test('mock function', () => { const fn = jest.fn();

    fn('Vanek'); fn('Ferdinand', 'Vanek'); expect(fn).toHaveBeenCalledWith('Vanek'); expect(fn).toHaveBeenCalledWith('Ferdinand', 'Vanek'); expect(fn).toHaveBeenCalledTimes(2); // vs expect(fn.mock.calls).toMatchSnapshot(); });
  9. SNAPSHOT exports[`method mock function 1`] = ` Array [ Array

    [ "Vanek", ], Array [ "Ferdinand", "Vanek", ], ] `;
  10. ?

  11. SNAPSHOT exports[`component with defaults`] = ` <div style={ Object {

    "backgroundColor": "black", "display": "flex", "flexDirection": “column", } }> <h1> …
  12. TEST SNAPSHOT exports[`method immutable 1`] = ` Immutable.Map { "a":

    1, "b": 2, } `; expect(Immutable.Map({ a: 1, b: 2 })).toMatchSnapshot();
  13. const plugin = { test(val) { return val && val.isPlay;

    }, serialize(val, config, indent, depth, refs, printer) { const name = val.constructor.name; const newIndent = indent + config.indent; return ( `Play <${val.title}>: ` + printer(val.content, config, newIndent, depth ++, refs) ); } }; SERIALISER
  14. TEST test('play', () => { const play = { isPlay:

    true, title: 'Audience', content: { scenes: 1 } }; expect([ play ]).toMatchSnapshot(); });
  15. TEST test('diff', () => { const play = { title:

    'Audience', characters: 2 }; expect(play).toMatchSnapshot(); expect({ ...play, characters: 3 }).toMatchSnapshot(); });
  16. SNAPSHOT exports[`diff 1`] = ` Object { "characters": 2, "title":

    "Audience", } `; exports[`diff 2`] = ` Object { "characters": 3, "title": "Audience", } `;
  17. const { toMatchDiffSnapshot } = require('snapshot-diff'); expect.extend({ toMatchDiffSnapshot }); test('diff',

    () => { const play = { title: 'Audience', characters: 2 }; expect(play) .toMatchDiffSnapshot({ ...play, characters: 3 }); });
  18. SNAPSHOT exports[`diff 1`] = ` "Snapshot Diff: - First value

    + Second value Object { - \\"characters \\": 2, + \\"characters \\": 3, \\"title \\": \\"Audience \\", }" `;
  19. // moduleA.spec.js const moduleA = require('./moduleA'); test('moduleA', () => {

    expect(moduleA()).toBe(true); }); // moduleA.js const moduleB = require('./moduleB'); DEPS
  20. PROMISES test('promises', () => { Promise.resolve(8).then(n => { expect(n).toBe(7); });

    return Promise.resolve(7).then(n => { expect(n).toBe(7); }); });
  21. REJECTION test('reject', () => { return Promise.reject(0).catch(n => { expect(n).toBe(0);

    }); }); test('reject', () => { return Promise.resolve(7).catch(n => { expect(n).toBe(0); }); });
  22. REJECTION test('reject', () => { expect.assertions(1); return Promise.resolve(7) .then(() =>

    { throw new Error('Not rejected!'); }) .catch(n => { expect(n).toBe(0); }); });
  23. ASYNC
 AWAIT test('async', async () => { const n =

    await Promise.resolve(7) const m = await Promise.resolve(42) expect(n).toBe(7) expect(m).toBe(42) })
  24. ASYNC
 AWAIT test('async', async () => { const n =

    Promise.resolve(7) const m = await Promise.resolve(42) expect(n).toBe(7) expect(m).toBe(42) })
  25. ASYNC REJECTION test('async rejection', async () => { try {

    await Promise.reject(0); } catch (e) { expect(e).toBe(0); } });
  26. ASYNC REJECTION test('async rejection', async () => { try {

    await Promise.resolve(7); } catch (e) { expect(e).toBe(0); } });
  27. ASYNC REJECTION test('async rejection', async () => { try {

    await Promise.resolve(0); expect(true).toBe(false); } catch (e) { expect(e).toBe(0); } });
  28. MOCK NAME test('mockName', () => { const mockFn = jest.fn();

    expect(mockFn).toHaveBeenCalled(); });
  29. MOCK NAME test('mockName', () => { const mockFn = jest.fn();

    expect(mockFn).toHaveBeenCalled(); }); test('mockName', () => { const mockFn = jest.fn().mockName('mockedFunction'); expect(mockFn).toHaveBeenCalled(); });
  30. RELATED • github.com/robinpokorny/jest-can-do-whaaat • Jest Snapshots and Beyond by Rogelio

    Guzman (recording) • Writing snapshot plugins in the docs • Effective Snapshot Testing by Kent C. Dodds • Async testing in Jest (recording) • Snapshot testing in Jest (recording) • Async testing Koa with Jest Full links in the description INFO