Reputation: 182
I'm complete beginner when it comes to writing tests, yet I have been given task to test some api's implementation, which is done using redux and redux-saga. The scenario is that user fills prepared form with his username, password and my generator function "authenticateUser" calls proper endpoint from api (api handlers were automatically generated from Swagger, and are imported from private registry), to create token and check whether user exists in database. If so, token is saved to session/local storage and store is updated with corresponding values.
import { userAuthenticated, userAuthenticationRejected } from "../actions/user";
import { call, put } from "redux-saga/effects";
import createApi from "@my-module";
export function* authenticateUser(action) {
const myApi = yield call(createApi, {
cors: true,
securityHandlers: {
Basic: () => true,
Bearer: () => true
}
});
try {
const response = yield call(myApi.token_create, {
data: {
username: action.payload.username,
password: action.payload.password
}
});
if (response.status === 200) {
const body = yield call([response, "json"]);
const accessToken = body.access;
window.sessionStorage.setItem("accessToken", accessToken);
if (action.payload.persistAuthenticationToken) {
window.localStorage.setItem("accessToken", accessToken);
}
yield put(
userAuthenticated({
username: action.payload.username,
accessToken
})
);
} else {
throw new Error("Unauthorized");
}
} catch (error) {
yield put(userAuthenticationRejected());
}
}
I got completely lost while reading about testing approaches. I've tried simple unit testing with consecutive "generator.next().value" but after first yield it couldn't even get into "try" block and throws out "undefined" sooner than expected.
test("User authentication", () => {
const action = {
payload: {
username: "test",
password: "test"
}
};
const generator = cloneableGenerator(authenticateUser)(action);
console.log(generator.next().value);
// {
// '@@redux-saga/IO': true,
// combinator: false,
// type: 'CALL',
// payload: {
// context: null,
// fn: [Function: createApi],
// args: [ [Object] ]
// }
// }
console.log(generator.next().value);
// {
// '@@redux-saga/IO': true,
// combinator: false,
// type: 'PUT',
// payload: {
// channel: undefined,
// action: { type: 'USER_AUTHENTICATION_REJECTED' }
// }
// }
console.log(generator.next().value);
// undefined
});
When I looked at integration tests, which seems to be preferred way, I couldn't just simply transfer relatively straightforward examples to my specific case.
I'll appreciate any help, because I just don't know where to start.
Upvotes: 2
Views: 2090
Reputation: 1568
You’ll need to pass in a mock value for your response object. I presume it’s undefined and your code throws if response.status
is anything other than 200. So for your se one call to generator.next().value
pass in a mock like so:
const responseMock = {
status: 200,
// anything else it needs
}
console.log(generator.next(reponseMock).value)
Upvotes: 1