使用 redux-saga-test-plan,我有一个将函数作为参数的调度操作。这使得测试总是失败
Using redux-saga-test-plan, I have a dispatch action that takes a function as an argument. This makes the test always fail
我有一个产生看跌期权的传奇。该 put 的参数之一是函数对象。
我只复制了相关的 saga 函数:
function* updateTaskTimeCancelledTimeRejectedSuccess(action) {
const {payload} = action.data
const tasks = yield select(getTasksSelector);
const parent = yield call(findExistingTaskParent, tasks, action.data.taskUUID);
if (action.type === taskActions.updateTaskCancelledTimeActions.success) {
const currentValue = parent.taskGroup[action.data.taskUUID].time_cancelled;
if (currentValue === null) {
// only notify if marking rejected for the first time
const restoreActions = yield () => [taskActions.updateTaskCancelledTimeRequest(
action.data.taskUUID,
{time_cancelled: null}
)];
const viewLink = `/task/${encodeUUID(action.data.taskUUID)}`
yield put(displayInfoNotification("Task marked cancelled", restoreActions, viewLink))
这是测试:
it("updates the task state with cancelled time and sends a notification", () => {
const action = {type: taskActions.updateTaskCancelledTimeActions.success, data: {taskUUID: "someUUID", time_cancelled: new Date().toISOString()}};
const restoreActions = () => [taskActions.updateTaskCancelledTimeRequest(
action.data.taskUUID,
{time_cancelled: null}
)];
const viewLink = `/task/${encodeUUID(action.data.taskUUID)}`
return expectSaga(testable.updateTaskTimeCancelledTimeRejectedSuccess, action)
.provide([
[select(getTasksSelector), {
tasksNew: {
1: {
someUUID: {
time_cancelled: null,
parent_id: 1
}
}
}
}]])
.put(displayInfoNotification("Task marked cancelled", restoreActions, viewLink))
.run()
})
})
这是结果:
SagaTestError:
put expectation unmet:
Expected
--------
{ '@@redux-saga/IO': true,
combinator: false,
type: 'PUT',
payload:
{ channel: undefined,
action:
{ type: 'DISPLAY_INFO_NOTIFICATION',
message: 'Task marked cancelled',
restoreActions: [Function: restoreActions],
viewLink: '/task/0000000000000000000000' } } }
Actual:
------
1. { '@@redux-saga/IO': true,
combinator: false,
type: 'PUT',
payload:
{ channel: undefined,
action:
{ type: 'DISPLAY_INFO_NOTIFICATION',
message: 'Task marked cancelled',
restoreActions: [Function],
viewLink: '/task/0000000000000000000000' } } }
at node_modules/redux-saga-test-plan/lib/expectSaga/expectations.js:48:13
at node_modules/redux-saga-test-plan/lib/expectSaga/index.js:544:7
at Array.forEach (<anonymous>)
at checkExpectations (node_modules/redux-saga-test-plan/lib/expectSaga/index.js:543:18)
对我来说很明显,由于 restoreActions 对象是不同引用的函数,所以相等性失败了。我不知道我应该怎么做才能通过测试。我需要做什么来验证 saga 是否按预期进行?我不一定需要验证函数的结果,只是发生了 displayInfoNotification。
谢谢。
为您的 restoreActions
lambda 创建一个工厂函数,然后您可以模拟它进行测试。
例如
// somewhere in your module
const actionRestoreFactory = (action) => () => [taskActions.updateTaskCancelledTimeRequest(action.data.taskUUID, {time_cancelled: null})]
//In your saga
yield put(displayInfoNotification("Task marked cancelled", actionRestoreFactory(action), viewLink))
//In your test
import actionRestoreFactory from './your/module'
jest.mock('./your/module')
actionRestoreFactory.mockReturnValue(jest.fn())
//...
return expectSaga(testable.updateTaskTimeCancelledTimeRejectedSuccess, action)
.provide([ ... ])
.put(displayInfoNotification("Task marked cancelled", actionRestoreFactory(action), viewLink))
.run()
我有一个产生看跌期权的传奇。该 put 的参数之一是函数对象。
我只复制了相关的 saga 函数:
function* updateTaskTimeCancelledTimeRejectedSuccess(action) {
const {payload} = action.data
const tasks = yield select(getTasksSelector);
const parent = yield call(findExistingTaskParent, tasks, action.data.taskUUID);
if (action.type === taskActions.updateTaskCancelledTimeActions.success) {
const currentValue = parent.taskGroup[action.data.taskUUID].time_cancelled;
if (currentValue === null) {
// only notify if marking rejected for the first time
const restoreActions = yield () => [taskActions.updateTaskCancelledTimeRequest(
action.data.taskUUID,
{time_cancelled: null}
)];
const viewLink = `/task/${encodeUUID(action.data.taskUUID)}`
yield put(displayInfoNotification("Task marked cancelled", restoreActions, viewLink))
这是测试:
it("updates the task state with cancelled time and sends a notification", () => {
const action = {type: taskActions.updateTaskCancelledTimeActions.success, data: {taskUUID: "someUUID", time_cancelled: new Date().toISOString()}};
const restoreActions = () => [taskActions.updateTaskCancelledTimeRequest(
action.data.taskUUID,
{time_cancelled: null}
)];
const viewLink = `/task/${encodeUUID(action.data.taskUUID)}`
return expectSaga(testable.updateTaskTimeCancelledTimeRejectedSuccess, action)
.provide([
[select(getTasksSelector), {
tasksNew: {
1: {
someUUID: {
time_cancelled: null,
parent_id: 1
}
}
}
}]])
.put(displayInfoNotification("Task marked cancelled", restoreActions, viewLink))
.run()
})
})
这是结果:
SagaTestError:
put expectation unmet:
Expected
--------
{ '@@redux-saga/IO': true,
combinator: false,
type: 'PUT',
payload:
{ channel: undefined,
action:
{ type: 'DISPLAY_INFO_NOTIFICATION',
message: 'Task marked cancelled',
restoreActions: [Function: restoreActions],
viewLink: '/task/0000000000000000000000' } } }
Actual:
------
1. { '@@redux-saga/IO': true,
combinator: false,
type: 'PUT',
payload:
{ channel: undefined,
action:
{ type: 'DISPLAY_INFO_NOTIFICATION',
message: 'Task marked cancelled',
restoreActions: [Function],
viewLink: '/task/0000000000000000000000' } } }
at node_modules/redux-saga-test-plan/lib/expectSaga/expectations.js:48:13
at node_modules/redux-saga-test-plan/lib/expectSaga/index.js:544:7
at Array.forEach (<anonymous>)
at checkExpectations (node_modules/redux-saga-test-plan/lib/expectSaga/index.js:543:18)
对我来说很明显,由于 restoreActions 对象是不同引用的函数,所以相等性失败了。我不知道我应该怎么做才能通过测试。我需要做什么来验证 saga 是否按预期进行?我不一定需要验证函数的结果,只是发生了 displayInfoNotification。
谢谢。
为您的 restoreActions
lambda 创建一个工厂函数,然后您可以模拟它进行测试。
例如
// somewhere in your module
const actionRestoreFactory = (action) => () => [taskActions.updateTaskCancelledTimeRequest(action.data.taskUUID, {time_cancelled: null})]
//In your saga
yield put(displayInfoNotification("Task marked cancelled", actionRestoreFactory(action), viewLink))
//In your test
import actionRestoreFactory from './your/module'
jest.mock('./your/module')
actionRestoreFactory.mockReturnValue(jest.fn())
//...
return expectSaga(testable.updateTaskTimeCancelledTimeRejectedSuccess, action)
.provide([ ... ])
.put(displayInfoNotification("Task marked cancelled", actionRestoreFactory(action), viewLink))
.run()