用Jest测试Redux-Saga catch错误处理

时间:2018-07-02 16:32:24

标签: testing redux jestjs anonymous-function redux-saga

我正在尝试测试我的传奇引发错误时是否调用了我的错误处理动作。

这是我的传奇代码:

function* createMenu({ values }) {
    try {
        do some stuff...
    } catch (err) {
        yield put(displayApiError(err));
    }
}

这是我的测试代码:

const saga = createMenu(mockAction);
const mockError = 'err';

it('calls displayApiError()', () => {
    saga.next();
    const result = saga.throw(mockError);

    expect(result.value).toEqual(put(displayApiError(mockError)));
});

这就是我在笑话输出中看到的:

● createMenu › Failure › calls displayApiError()

expect(received).toEqual(expected)

Expected value to equal:
  {"@@redux-saga/IO": true, "PUT": {"action": [Function anonymous], "channel": null}}
Received:
  {"@@redux-saga/IO": true, "PUT": {"action": [Function anonymous], "channel": null}}

Difference:

Compared values have no visual difference.

我假设这是问题所在的Function anonymous部分。我尝试自己执行两个比较函数,它们都以相同的方式调用displayApiError

那为什么测试仍然失败?

2 个答案:

答案 0 :(得分:0)

displayApiError(mockError)的内容是什么?好像您要返回一个thunk或匿名函数? Sagas put可使用普通的redux动作。

关于在redux sagas中测试匿名函数的一些一般想法:

  1. 如果您只关心声明效果而不是函数本身。

    const callEffect = call(() => {});  
    callEffect.CALL.fn = expect.any(Function);  
    expect(result.value).toEqual(callEffect);  
    

expect.any(Function)传递到诸如call之类的一些传奇效果时,可能会引起注意,因为它们断言了类型。

  1. 检查值的内容,而不是直接在效果上使用toEqual。

    const fn = result.value.CALL.fn;  
    const result = fn();  
    // then assert something about result
    

答案 1 :(得分:0)

重写您的传奇以使用call effect;

function* createMenu({ values }) {
    try {
        do some stuff...
    } catch (err) {
        const action = yield call(displayApiError, err)
        yield put(action);
    }
}

现在可以测试

const saga = createMenu(mockAction);
const mockError = 'err';
const mockActiom = {};

it('calls displayApiError()', () => {
    saga.next();
    let result  = saga.throw(mockError);

    // now you are actually testing that displayApiError been called
    // not that the event was dispatched
    expect(result.value).toEqual(call(displayApiError, mockError));

    // test for dispatch if necessary
    result = saga.next(mockAction);
    expect(result.value).toEqual(put(mockAction));
});