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

Jest can do whaaat?

Avatar for Robin Pokorny 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)

Avatar for Robin Pokorny

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