Jest can do whaaat?

073b377c7d0280cd8ca8c97cd3e7eaf4?s=47 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)

073b377c7d0280cd8ca8c97cd3e7eaf4?s=128

Robin Pokorny

November 01, 2017
Tweet

Transcript

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

    2017 @robinpokorny
  2. 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
  3. WHAT IS JEST delightful, zero configuration testing platform Jasmine’s and

    Expect’s successor practical utilities for awesome DX http:/ /facebook.github.io/jest/
  4. SNAPSHOT TESTING

  5. {JSON} A

  6. {JSON} {JSON} A B

  7. {JSON} {JSON} A B != !

  8. 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(); }); });
  9. 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`;
  10. SNAPSHOT ` Object { "bool": true, "func": [Function], "map": Map

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

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

    full = { … }; expect(full).toMatchSnapshot('new name'); }); }); SNAPSHOT exports[`new name 1`] = `…`
  13. 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(); });
  14. SNAPSHOT exports[`method mock function 1`] = ` Array [ Array

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

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

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

    1, "b": 2, } `; expect(Immutable.Map({ a: 1, b: 2 })).toMatchSnapshot();
  18. 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
  19. SERIALISER expect.addSnapshotSerializer(plugin); // package.json { ... "jest": { "snapshotSerializers": ["plugin.js"]

    } } or
  20. TEST test('play', () => { const play = { isPlay:

    true, title: 'Audience', content: { scenes: 1 } }; expect([ play ]).toMatchSnapshot(); });
  21. SNAPSHOT exports[`method play 1`] = ` Array [ Play <Audience>:

    Object { "scenes": 1, }, ] `;
  22. TEST test('diff', () => { const play = { title:

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

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

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

    + Second value Object { - \\"characters \\": 2, + \\"characters \\": 3, \\"title \\": \\"Audience \\", }" `;
  26. structures concurrent or after whole algorithms write before part TDD

    SNAPSHOTS ✖ inside codebase
  27. watch

  28. $ jest --watch $ npm test -- --watch

  29. understands dependencies filter by Path or Test name Update snapshots

    failed re-run first
  30. // moduleA.spec.js const moduleA = require('./moduleA'); test('moduleA', () => {

    expect(moduleA()).toBe(true); }); // moduleA.js const moduleB = require('./moduleB'); DEPS
  31. None
  32. None
  33. in JEST ASYNC testing

  34. test('promise', done => { Promise.resolve(7) .then(n => { expect(n).toBe(7); })

    .then(done) .catch(done.fail); }); CALLBACK
  35. PROMISES test('promises', () => { Promise.resolve(8).then(n => { expect(n).toBe(7); });

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

    }); });
  39. 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); }); });
  40. REJECTION test('reject', () => { expect.assertions(1); return Promise.resolve(7) .then(() =>

    { throw new Error('Not rejected!'); }) .catch(n => { expect(n).toBe(0); }); });
  41. None
  42. 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) })
  43. ASYNC
 AWAIT test('async', async () => { const n =

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

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

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

    await Promise.resolve(0); expect(true).toBe(false); } catch (e) { expect(e).toBe(0); } });
  48. .RESOLVES
 & .REJECTS test('resolves/rejects', async () => { await expect(Promise.resolve(7)).resolves.toBe(7);

    await expect(Promise.reject(0)).rejects.not.toBe(7); });
  49. None
  50. JEST can do whaaat? will do

  51. MOCK NAME test('mockName', () => { const mockFn = jest.fn();

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

    expect(mockFn).toHaveBeenCalled(); }); test('mockName', () => { const mockFn = jest.fn().mockName('mockedFunction'); expect(mockFn).toHaveBeenCalled(); });
  54. GIF not supported in PDF INFO

  55. $ jest packages/moduleA $ jest packages/moduleA --passWithNoTests

  56. by @kentcdodds GIF not supported in PDF INFO

  57. 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
  58. JEST can do whaaat? @robinpokorny Help others to go