首页 > 解决方案 > Redux Saga Unit Testing with jest:如何在测试中维持接受的对象?

问题描述

我是单元测试、Redux 和 Redux Saga 的新手。我将它与 React Native 一起使用。我刚刚实现了我loginFlow的,就像Redux Saga 文档中描述的那样:

function* loginFlow() {
  while (true) {
    const {user, password} = yield take('LOGIN_REQUEST')
    // fork return a Task object
    const task = yield fork(authorize, user, password)
    const action = yield take(['LOGOUT', 'LOGIN_ERROR'])
    if (action.type === 'LOGOUT')
      yield cancel(task)
    yield call(Api.clearItem, 'token')
  }
}

function* authorize(user, password) {
  try {
    const token = yield call(Api.authorize, user, password)
    yield put({type: 'LOGIN_SUCCESS', token})
    yield call(Api.storeItem, {token})
    return token
  } catch(error) {
    yield put({type: 'LOGIN_ERROR', error})
  } finally {
    if (yield cancelled()) {
      // ... put special cancellation handling code here
    }
  }
}

我现在正在尝试为此 Auth 流程编写测试。不幸的是,我不知道如何为*loginFlow生成器的测试提供电子邮件和密码。这是我目前所在的位置:

describe("login flow", () => {
  const gen = loginFlow();
  const user = "test@test.test";
  const password = "testpassword";

  it("should wait for a user to log in", () => {
    expect(gen.next({ user, password }).value).toEqual(take(LOGIN_REQUEST));
  });

  it("should fork the handling of the login request", () => {
    const expectedYield = fork(authorize, user, password);
    expect(gen.next().value).toEqual(expectedYield);
  });
});

问题是,这会引发错误:

● login flow › should fork the handling of the login request

    TypeError: Cannot read property 'email' of undefined

      28 | export function* loginFlow() {
      29 |   while (true) {
    > 30 |     const { email, password } = yield take(LOGIN_REQUEST);

         |             ^
      31 |     // fork return a task object
      32 |     const task = yield fork(authorize, email, password);
      33 |     const action = yield take([LOGOUT, LOGIN_ERROR]);

如您所见,我试图通过在下一次调用中提供这些值来将这些值提供给 yield 关键字,但它不起作用。

标签: unit-testingreduxjestjsredux-sagaredux-saga-test-plan

解决方案


在尝试了很多之后,我才发现它。

这是我必须更改测试的方法:

describe("login flow", () => {
  const gen = loginFlow();
  const email = "test@test.test";
  const password = "testpassword";

  it("should wait for a user to log in", () => {
    expect(gen.next().value).toEqual(take(LOGIN_REQUEST));
  });

  it("should fork the handling of the login request", () => {
    const expectedYield = fork(handleLoginRequest, email, password);
    expect(gen.next({ email, password }).value).toEqual(expectedYield);
  });
});

推荐阅读