当某些功能未使用“收益率”或诸如“看涨”或“放盘”之类的效果时,如何测试saga?

时间:2019-09-03 21:45:28

标签: javascript redux redux-saga redux-saga-test-plan

在所有示例中,我发现每个人都在他们的sagas上使用yield call()yield put()等。现在,我有了一个传奇,它无需执行yield call()就可以执行一个函数。该函数在选择效果之后和调用效果之前执行(请参见下面的service变量代码。该函数返回类的实例,它不是网络请求或诺言。

这个传奇作品很好,但是我不确定如何测试它。在产生效果的同时使用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' } } }

2 个答案:

答案 0 :(得分:1)

每次在传奇中调用函数时,都应使用call效果。最好使用它,而不是像已经完成的那样直接调用该函数。它会返回与直接调用时相同的数据,并且由于您不必模拟或监视任何东西,因此使测试变得更加容易。

示例:

export function* getDetails() {
    try {
        const config = yield select(getProperties());
        const service = yield call(getService, config);
        const data = yield call([service, service.getDetails]);
        yield put(success(data));
    } catch(e) {
        yield put(failure());
    }
}

答案 1 :(得分:1)

根据我发现的其他示例,这是我的解决方案:

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来调用,但是在此我不被要求这样做。