mercredi 22 février 2017

Testing redux-saga with try-catch best practices

How can I test a saga with Try-catch blocks, reaching all scenarios? I'm using ava as test framework, Is that approach a good one? Anyone else has another way to do that.

My Login saga:

export function * loginUserSaga (action) {
  try {
    const user = yield call(callFirebaseSignIn, action.payload)
    yield call(success, user)
  } catch (e) {
    yield put(signupUser(action.payload))
  }
}

export function * signupUserSaga(action) {
  try {
    const user = yield call(createFirebaseUser, action.payload)
    yield call(success, user)
  } catch (e) {
    yield put(loginUserFailed(e.message))
  }
}

export function * success (user) {
  yield put(loginUserSuccess())
  yield put(userLoggedIn(user))
}

export const callFirebaseSignIn = (credential) => {
  return api.signInWithEmailAndPassword(credential.email, credential.password)
}

export const createFirebaseUser = (credential) => {
  return api.createUserWithEmailAndPassword(credential.email, credential.password)
}

My test file:

const sagaDone = { done: true, value: undefined }
const credential = { email: 'email', password: 'pass' }
const loginAction = loginUser(credential)
const signUpAction = signupUser(credential)
const expectedUser = { user: 'Fake'}

test('Sign in perfect flow', t => {
  const generator = loginUserSaga(loginAction);
  const step = (lastYield) => generator.next(lastYield)

  t.deepEqual(step().value, call(callFirebaseSignIn, loginAction.payload))
  t.deepEqual(step(expectedUser).value, call(success, expectedUser))
  t.deepEqual(step(), sagaDone)
})

test('Sign in flow should call signup flow on error', t => {
  const generator = loginUserSaga(loginAction);

  try {
    t.deepEqual(generator.next().value, call(callFirebaseSignIn, loginAction.payload))
    t.deepEqual(generator.throw('Failed to login').value, put(signupUser(loginAction.payload)), 'If the last yield throws an exception, call signUp saga')
  } finally {
    t.deepEqual(generator.next(), sagaDone)
  }
})

test('Sign Up perfect flow', t => {
  const generator = loginUserSaga(loginAction);
  const step = (lastYield) => generator.next(lastYield)

  t.deepEqual(step().value, call(callFirebaseSignIn, loginAction.payload))
  t.deepEqual(step(expectedUser).value, call(success, expectedUser))
  t.deepEqual(step(), sagaDone)
})

test('Sign Up error flow', t => {
  const generator = signupUserSaga(signUpAction)
  const error = { message: 'Error Message' }

  try {
    t.deepEqual(generator.next().value, call(createFirebaseUser, signUpAction.payload))
    t.deepEqual(generator.throw(error).value, put(loginUserFailed(error.message)))
  } finally {
    t.deepEqual(generator.next(), sagaDone)
  }
})


test('On Success should Update State', t => {
  const generator = success(expectedUser)
  const step = (lastYield) => generator.next(lastYield)

  t.deepEqual(step().value, put(loginUserSuccess()), 'Update state of Login Screen')
  t.deepEqual(step().value, put(userLoggedIn(expectedUser)), 'Put user object under state.user')
  t.deepEqual(step(), sagaDone)
})

Thanks Guys!

Aucun commentaire:

Enregistrer un commentaire