3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

epic-tester で redux-observable のマーブルテストを簡潔にする

Posted at

マーブルテストは強力ですが、そのための準備(before,after)は面倒で極力書きたくありません。ここでは、epic-testerを使って簡潔に書く方法を見ていきます。

マーブルテストについては以下のブログが詳しいです。

redux-observable の処理を marble testing で簡単にテストする
RxJS(5.x)で行うテストファーストな機能開発 | MMMブログ

準備

準備として以下のような Epic を用意します。

const success = payload => ({ type: 'success', payload })
const failure = error => ({ type: 'failure', error })

const epic = (action$, _, { API }) =>
  action$.ofType('fetchUser').mergeMap(() => {
    return API.getUser()
      .map(v => success(v.data))
      .catch(err => Observable.of(failure(err)))
  })

マーブルテスト

まずは、epic-tester導入前のテストを見てみます。一つのitが大きいので、数が増えると記述量も増えていくのが予測できます。

import { Observable } from 'rxjs'

beforeEach(() => {
  jest.resetModules()

  testScheduler = new TestScheduler((expected, actual) => {
    expect(expected).toEqual(actual)
  })

  cold = createCold(testScheduler)
})

afterEach(() => {
  testScheduler.flush()
})

describe('API success', () => {
  it('fetchUser', () => {
    const values = {
      a: { type: 'fetchUser' },
      b: { type: 'success', payload: 'result' }
    }

    const input$ = '--a'
    const expect = '--b'
    const test$ = epic(
      new ActionsObservable(cold(input$, values)),
      {},
      {
        dependencies: {
          API: { fetchUser: () => Observable.of({ data: 'result' }) }
        }
      }
    )
    testScheduler.expectObservable(test$).toBe(expect, values)
  })
})

epic-testerを導入しこれを解消していきましょう。

インストール

yarn add --dev epic-tester

使い方

title、epic、tests プロパティが必須です。
tests プロパティはオブジェクトの配列を取ります。それぞれ、input$に入力、expect$に期待する出力をマーブル記法で書きます。values はマーブル記法で使ったプロパティを指定します。

import { Observable } from 'rxjs'
import { epicTester } from 'epic-tester'

epicTester({
  title: 'API success',
  epic,
  dependencies: {
    API: {
      getUser: () => Observable.of({ data: 'result' })
    }
  },
  tests: [
    {
      title: 'fetchUser',
      input$: '-a',
      expect$: '-b',
      values: {
        a: { type: 'fetchUser' },
        b: {
          type: 'success',
          payload: 'result'
        }
      }
    }
  ]
})

beforeEachや expect 部分が抽象されたので、対象のマーブル記法を書くだけになりました。これで、新しくテスト対象が増えてもtestsプロパティにテスト対象を加えるだけです。

まとめ

欠点としてはepicTesterでは複雑なObservableのテストに対処できないでしょう。しかし、簡単なものを複雑なものに合わせる道理はありません。簡単なものは、簡潔に書くべきです。

何かあれば、コメントまたは Twitter でフィードバックお願いします 🙏

さて、ここで、reducer のテストも同様に簡潔に書けることに気づきます。reducer については、以下の記事を見てください。

どのように redux の reducer のテストを書くか? - Qiita

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?