Skip to content

Instantly share code, notes, and snippets.

@kimniche
Last active May 3, 2021 13:56
Show Gist options
  • Save kimniche/fff58faaf2768a09e2e4e4a258d906cc to your computer and use it in GitHub Desktop.
Save kimniche/fff58faaf2768a09e2e4e4a258d906cc to your computer and use it in GitHub Desktop.

General structure

  • very similar to Website tests
import { isLegitAdmin } from 'utils/UserUtils'

describe('UserUtils', () => {
    it('`isLegitAdmin` returns false if no `user` is provided', () => {
        expect(isLegitAdmin()).toBe(false)
    })
    
    ...
})

Selectively running or skipping tests/suites is virtually the same

// Website/Mocha & Jest
describe.only( ... )
it.only('foo', () => { ... })
// Website/Mocha & Jest
xit('bar', () => { ... })

Note: Jest supports both it- and test-style tests:

test('is legit', () => {
    expect(something).toBeTruthy
})

// is the same as
it('is legit', () => {
    expect(something).toBeTruthy
})

Assertions

strict equality

// Website/Chai
expect(y).to.eql(12)

// Jest
expect(y).toBe(12)

truthy and falsy

// Website/Chai
expect(z).to.be.ok
expect(a).to.not.be.ok

// Jest
expect(z).toBeTruthy()
expect(a).toBeFalsy()

negating

// Website/Chai
expect(y).to.not.eql(11)

// Jest
expect(y).not.toBe(11)

type checking

https://facebook.github.io/jest/docs/expect.html#expectanyconstructor

// Website/Chai
expect(result).to.be.an('array')
expect(result).to.be.an('object')

// Jest
expect(result).toEqual(expect.any(Array))
expect(result).toEqual(expect.any(Object))

expect.anything() can be used inside toEqual or toBeCalledWith instead of a literal value

object properties

https://facebook.github.io/jest/docs/expect.html#tohavepropertykeypath-value

// Website/Chai
expect(result).to.have.property('type', 'school')

// Jest
expect(result).toHaveProperty('type', 'school')

```es6
// Jest
expect(data).toEqual({ one: 1, two: 2 })

toEqual recursively checks every field of an object or array.

array content

// Website/Chai
expect(result).to.have.all.keys([ 0, 1 ])

// Jest
expect(result).toEqual(expect.arrayContaining([ 0, 1 ]))

function presence

// Website/Chai 
expect(someFunc).to.exist.and.be.a('function')

// Jest
expect(someFunc).toBeDefined()

checking that a function was executed

https://facebook.github.io/jest/docs/expect.html#tohavebeencalled

// Website/Chai
const doSomethingSpy = sinon.spy()
someFunction({ doSomething: doSomethingSpy })

expect(doSomethingSpy.called).to.be.true

// Jest
const doSomething = jest.fn()
someFunction({ doSomething: doSomethingSpy })

expect(x).toHaveBeenCalled()
// same as
expect(x).toBeCalled()
// same as
expect(x.mock.calls.length).toBeGreaterThan(0)

checking function call arguments - generic

https://facebook.github.io/jest/docs/mock-functions.html#custom-matchers

// Website/Sinon
const doSomethingSpy = sinon.spy()
someFunction({ doSomething: doSomethingSpy })

expect(doSomethingSpy.calledWith('niche')).to.be.true

// Jest
const doSomething = jest.fn()
someFunction({ doSomething: doSomethingSpy })

expect(x).toBeCalledWith('niche')
// same as
expect(x.mock.calls).toContain(['niche'])

Note: .toBeCalled, .toBeCalledWith, & lastCalledWith are "custom matchers" in the Jest world, wrappers around the mock's .mock property that contains more details about the function calls.

checking function call arguments - granular

Recall that the .[0][0] syntax means the first arg to the first call; .[1][0] would be first arg to the second call

// Website/Sinon
const dispatch = sinon.spy()
...
expect(dispatch.args[0][0]).to.eql('foo')


// Jest
const dispatch = jest.fn()
...
expect(dispatch.mock.calls[0][0]).toEqual('foo')

Testing private methods

With Jest, we only need babel-plugin-rewire, babel-jest, and a corresponding entry in .babelrc to hook up auto-rewiring to facilitate private method testing. There's no need to explicitly import rewire from 'rewire' (or similar)

// Website/rewire
const utils = rewire('../../common/utils/date-utils')

it('has expected private functions', () => {
    const privateMethods =  ['_getDependencies', '_shouldNormalize' ]
    
    privateMethods.forEach(method => {
        expect(utils.__get__(method)).to.exist.and.be.a('function')
    })
})

it('`shouldNormalize` returns false for a leap year birthday provided as array of strings', () => {
    const _shouldNormalize = utils.__get__('_shouldNormalize')
    const bday = ['02', '29', '2000']
    expect(_shouldNormalize(bday)).to.be.false
})

// Jest
import utils from 'common/utils/date-utils'

it('has expected private methods', () => {
    const privateMethods = [ '_getDependencies', '_shouldNormalize' ]

    privateMethods.forEach(m => {
        expect(utils.__GetDependency__(m)).toBeDefined
    })
})

it('`shouldNormalize` returns false for a leap year birthday provided as array of strings', () => {
    const _shouldNormalize = utils.__GetDependency__('_shouldNormalize')
    const bday = ['02', '29', '2000']
    expect(_shouldNormalize(bday)).toBe(false)
})

Async/await

https://facebook.github.io/jest/docs/tutorial-async.html#async-await

If your code under test is async, just wrap the test in async:

it('`submitForm` calls `post`', async () => {
  await ...
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment