I'm new to Unit testing, Redux and Redux Saga. I use it with React Native. I just implemented my loginFlow
just like the one described in the docs of 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
}
}
}
I'm now trying to write tests for this Auth flow. Unfortunately iI can't figure out how to give the test for the *loginFlow
generator the email and the password. Here is where I'm currently at:
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);
});
});
The problem is, that this throws the error:
● 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]);
As you can see I tried to give these values to the yield keyword by supplying them in the next call, but it just won't work.
After trying a lot I just found it out.
Here is how I had to change the test:
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);
});
});