[英]Can't unit test redux-saga with selector function using Jest
問題說明:
我想使用 Jest 對 redux-saga 進行單元測試。 我正在按照 redux-saga 文檔中提供的示例中描述的方式執行此操作: https : //redux-saga.js.org/docs/advanced/Testing.html
在我的 Saga 中,我正在調用一個選擇器函數selectSet
,它從應用程序商店返回一個特定的對象:
export const selectSet = state => state.setStore.set
在我的傳奇中,我試圖產生這個選擇器函數:
import { put, select } from 'redux-saga/effects'
import { selectSet } from '../selectors'
export function* getSet() {
try {
const set = yield select(selectSet)
yield put({ type: 'SET_SUCCESS', payload: { set } })
} catch (error) {
yield put({ type: 'SET_ERROR', payload: { error } })
}
}
在我的測試中,沒有有效的應用程序商店,所以我必須模擬函數以返回預期的對象:
import assert from 'assert'
import * as AppRoutines from './AppRoutines'
import { put, select } from 'redux-saga/effects'
describe('getSet()', () => {
it('should trigger an action type "SET_SUCCESS" with a payload containing a valid set', () => {
const generator = AppRoutines.getSet()
const set = {
id: 1,
slots: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
}
const selectSet = jest.fn()
selectSet.mockReturnValue(set)
// Saga step 1
const actualFirst = generator.next().value
const expectedFirst = select(selectSet)
assert.deepEqual(
actualFirst,
expectedFirst,
'it should retreive a valid set from the store using the selectSet selector'
)
})
})
但是 - 如果我使用deepEqual
和我的deepEqual
函數斷言 saga 返回特定的生成器值,它希望我的選擇器函數具有原始的selectSet
構造函數。 但是因為我用 jest.fn() 模擬函數,構造函數實際上等於mockConstructor
- 這使我的測試失敗:
Expected value to deeply equal to:
{"@@redux-saga/IO": true, "SELECT": {"args": Array [], "selector": [Function mockConstructor]}}
Received:
{"@@redux-saga/IO": true, "SELECT": {"args": Array [], "selector": [Function selectSet]}}
問題:如何制作包含模擬函數的 assert.deepEqual 而不沖突構造函數類型?
替代問題:有沒有辦法讓我的斷言期望一個mockConstructor
而不是實際的selectSet
構造函數?
您根本不需要模擬選擇器,因為在這種性質的 saga 測試中,從未實際調用選擇器,而是測試為 redux saga 中間件創建的聲明性指令以進行操作,如您所料
這是 saga 將創建的指令{"@@redux-saga/IO": true, "SELECT": {"args": Array [], "selector": [Function selectSet]}}
,但作為中間件在此測試場景中未運行selectSelect
將永遠不會被實際調用
如果您需要模擬選擇器為您的操作返回的結果,那么您可以通過將模擬數據傳遞到下一步來實現...
const set = {
id: 1,
slots: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
}
// Saga step 1
const firstYield = generator.next().value
assertDeepEqual(firstYield, select(selectSet))
// Step 2 - successful so dispatch action
// mock data from the previous yield by passing into this step via `next(stubbedYieldedData)`
const secondYield = generator.next(set).value
assertDeepEqual(secondYield, put({type: 'SET_SUCCESS', payload: {set} }))
我們可以在一個假商店中傳遞模擬商店,如下所示。 下面是示例選擇器和生成器函數及其測試。
選擇器
const authSelector = (state) => state.authReducer || initialState;
傳奇生成器功能
export function* getAuthToken(action) {
try {
const authToken = yield select(makeSelectAuthToken());
} catch (errObj) {}
}
測試用例
import { runSaga } from 'redux-saga'
const dispatchedActions = [];
const fakeStore = {
getState: () => ({ authReducer: { auth: 'test' } }),
dispatch: (action) => dispatchedActions.push(action)
}
await runSaga(fakeStore, getAuthToken, {
payload: {}
}).done;
expected case you can write here below this
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.