Протестируйте Redux-Saga 'yield call'

Я пытаюсь написать модульный тест на следующую сагу:

function * verifyCode(api){
    let action =  yield take(LoginTypes.VERIFY_CODE)
    const phoneNumber = yield select(phoneNumberSelector)
    try{
      const response = yield call(api.verifyCode, phoneNumber, action.code)
      if (response.ok){
        let token = response.data.token
        yield put(LoginActions.verifyCodeSuccess(response.data.token))
      }
      else {
        yield put(LoginActions.verifyCodeFailure(response.error))
      }
    }
    catch(error){
      yield put(LoginActions.verifyCodeFailure(error))
    }
}

Все тесты проходят до части 'yield call', используя следующее (используя тест с 'ленты'):

test('verify code flow', (assert) => {
  let number = '0000000'
  let code = '00000'
  const gen = verifyCode(api)


  assert.deepEqual(
      gen.next({code: code}).value,
      take(LoginTypes.VERIFY_CODE),
      'wait for verify code action from user',
  )

  assert.deepEqual(
    gen.next().value,
    select(phoneNumberSelector),
    'get phoneNumber from login state'
  )
    assert.deepEqual(
      gen.next().value,
      call(api.verifyCode, number, code),
      'call verify code'
    )
  assert.end()
})

Ошибка, которую я получаю из-за провала этого теста:

   operator: deepEqual
expected: |-
  { '@@redux-saga/IO': true, CALL: { context: null, fn: [Function: verifyCode], args: [ '0000000', '00000' ] } }
actual: |-
  { '@@redux-saga/IO': true, PUT: { channel: null, action: { type: 'VERIFY_CODE_FAILURE', error: [TypeError: Cannot read property 'code' of undefined] } } }
  1. Как правильно писать в вызов API с использованием эффекта «вызова»?
  2. Как я могу протестировать различные возможные потоки в зависимости от того, какой ответ я получаю?

person Inbar S    schedule 19.09.2017    source источник


Ответы (1)


  1. Это правильный способ использования эффекта вызова в API.
  2. Для тестирования различных потоков (Успех | Ошибка) вы можете использовать следующий шаблон (в Jest):
expect(generator.next().value.PUT.action).toMatchObject({type: types.VERIFY_CODE_SUCCESS, payload: {}, meta: { section }});

expect(generator.throw('error').value.PUT.action).toMatchObject({ type: VERIFY_CODE_FAILURE, payload: 'error'});

Кстати: похоже, что ваш тест не прошел из-за ошибки, возникшей при вызове конечной точки API. Убедитесь, что вы получаете желаемый ответ от своей конечной точки.

Удачи!

person Tomer    schedule 02.04.2019