jest-generator

February 16, 2021 ยท View on GitHub

npm Build Status GitHub PRs Welcome

Testing generators are verbose as they require calling next method of generator each time you want to iterate. jest-generator encapsulates all iteration and assertion logic itself. It provides easy and readable API for testing generator functions.

Testing with jest-generator

Installation


yarn add --dev jest-generator

or


npm install --save-dev jest-generator

Setup

Via setupTestFrameworkScriptFile config

Add jest-generator to your Jest setupTestFrameworkScriptFile configuration

"jest": {
  "setupTestFrameworkScriptFile": "jest-generator"
}

Via setupTest script

Require jest-generator from setupTest script

// ./setupTest.js

require('jest-generator');

Then add this config

"jest": {
  "setupTestFrameworkScriptFile": "./setupTest.js"
}

Usage

// ./pay.js

export default function* pay() {
  yield validatePayment();
  yield makePayment();

  return finishPayment();
}
// ./pay.test.js

import pay from './pay';

test('should work correctly', () => {
  const iterator = pay();

  expect(iterator).toMatchYields([
    [validatePayment()],
    [makePayment()],
    [finishPayment()]
  ]);
});

Usage with other libraries

Usage with Saga

// ./books.js

export function* loadBooks(params) {
  try {
    const response = yield call(api.loadBooks, params)
    
    yield put(booksLoadedSuccess(response))
  } catch (error) {
    yield put(booksLoadFail(error.message))
  }
}
// ./books.test.js

import { loadBooks } from './books';

test('should handle success response', () => {
  const params = { id: 201 };
  const iterator = loadBooks(params);
  const response = [];

  expect(iterator).toMatchYields([
    [call(api.loadBooks, params), response],
    [booksLoadedSuccess(response)],
  ]);
});

test('should handle error response', () => {
  const params = { id: 201 };
  const iterator = loadBooks(params);
  const response = new Error('failed to load books');

  expect(iterator).toMatchYields([
    [call(api.loadBooks, params), response],
    [put(booksLoadFail(response.message))],
  ]);
});

API

.toMatchYields(
  yieldValues: [
    [yieldValue: any, returnType?: any | Error]
  ]
)

Matches iterator against given yield values

expect(iterator).toMatchYields([
  [callAPI()]
])

In order to return value from yield, simply pass your return value as second array value

function* gen() {
  const response = yield fetch()
  yield update(response)
}

const mockResponse = {};
const iterator = gen();

expect(iterator).toMatchYields([
  [fetch(), mockResponse],
  [update(mockResponse)]
])

In order to throw error from yield, you should simply pass Error instance to return type

function* gen() {
  const response = yield fetch()
  yield update(response)
}

const mockErrorResponse = new Error('network error');
const iterator = gen();

expect(iterator).toMatchYields([
  [fetch(), mockErrorResponse],
  [handleError(mockErrorResponse)]
])

Licence

This project is licensed under the MIT License - see the LICENSE file for details