在所有示例中,我发现每个人都在他们的传奇中使用 yield call()
、yield put()
等。现在我有一个传奇,它只执行一个函数而不使用yield call()
。该函数在选择效果之后和调用效果之前执行(有关 service
变量,请参阅下面的代码。该函数返回类的实例,它不是网络请求或 promise 。
这个传奇运作良好,但我不知道如何像这样测试它。在具有效果的情况下使用 redux-sagas-test-plan 效果很好,但是一旦我删除效果(我从 .provide() 中删除它),测试失败。
传奇
export function* getDetails() {
try {
const config = yield select(getProperties());
const service = getService(config);
const data = yield call([service, service.getDetails]);
yield put(success(data));
} catch(e) {
yield put(failure());
}
}
测试
import { getDetails as detailsSaga } from '...';
const data = {};
it('should succeed getting details', async () => {
await expectSaga(detailsSaga)
.provide([
[select(getProperties), {}],
[call([serviceMock, serviceMock.getDetails]), data]
])
.put(success(data))
.dispatch(fetchDetails())
.silentRun();
});
测试的预期结果是您要执行 success(data)
创建者,但我得到的是 failure()
创建者作为实际值。
Expected
--------
{ '@@redux-saga/IO': true,
combinator: false,
type: 'PUT',
payload:
{ channel: undefined,
action:
{ type: 'FETCH_DETAILS_SUCCESS',
data: { } } } }
Actual:
------
1. { '@@redux-saga/IO': true,
combinator: false,
type: 'PUT',
payload:
{ channel: undefined,
action: { type: 'FETCH_DETAILS_FAILURE' } } }
最佳答案
根据我发现的其他示例,这是我的解决方案:
import { call } from 'redux-saga-test-plan/matchers';
beforeEach(() => {
service = getService({});
data = { /* ... */ });
});
it('should succeed getting details', async () => {
await expectSaga(detailsSaga)
.provide([
[select(getProperties), {}],
[call.fn(service.getDetails), data]
])
.put(success(data))
.dispatch(fetchDetails())
.silentRun();
});
我必须使用 redux-saga-test-plan/matchers 的调用效果并创建 getService 返回的实际实例。由于某种原因,模拟在这里不起作用。
我不太清楚为什么这样做的细节,但我写这个答案只是为了防止有人也试图实现这一目标。注意:我同意另一个答案,即所有函数都应该使用 yield call
来调用,但我被要求不要在这里这样做。
关于javascript - 当存在不使用 'yield' 的函数或类似 'call' 或 'put' 的效果时,如何测试传奇?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57779103/