マーブルテストは強力ですが、そのための準備(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 については、以下の記事を見てください。