Cześć,
próbuję zrozumieć koncepcję pisania testów jednostkowych dla aplikacji frontendowych. Stworzyłem prosty higher order reducer, aby zaoszczędzić sobie czasu przy pisaniu standardowych reducerów do reduxowych asynchroniczych akcji, ale nie mam pojęcią jak to sensownie przetestować. Dodatkowo, zastanawia mnie, czy korzystam z flow w poprawny sposób.
Funkcja:
// @flow
type action = {
type: string,
payload?: any
};
/**
* Async Reducer Factory to reduce duplicated code in async reducers.
* Higher Order Reducer.
*
* @param {String} name - Reducer name.
* @returns {Function}
*/
export const asyncReducerFactory = (name: String) => {
return (
state = { data: null, isLoading: false, error: null },
action: action
) => {
switch (action.type) {
case `FETCH_${name}_STARTED`:
return { data: null, isLoading: true, error: null };
case `FETCH_${name}_SUCCESS`:
return { data: action.payload, isLoading: false, error: null };
case `FETCH_${name}_ERROR`:
return { data: null, isLoading: false, error: action.payload };
default:
return state;
}
};
};
Testy:
import { asyncReducerFactory } from "./factories";
describe("Test async reducers factory", () => {
const factory = asyncReducerFactory("TEST");
it("should create reducer", () => {
expect(factory).not.toBe(null);
});
it("should start fetching", () => {
expect(factory({}, { type: "FETCH_TEST_STARTED" })).toEqual({
data: null,
isLoading: true,
error: null
});
});
it("should end fetching with success", () => {
expect(
factory({}, { type: "FETCH_TEST_SUCCESS", payload: "success" })
).toEqual({
data: "success",
isLoading: false,
error: null
});
});
it("should end fetching with error", () => {
expect(
factory({}, { type: "FETCH_TEST_ERROR", payload: "error" })
).toEqual({
data: null,
isLoading: false,
error: "error"
});
});
it("should return default state", () => {
expect(factory({}, { type: "DIFFERENT" })).toEqual({});
});
});
Czy nazwy akcji powinienem wydzielić do osobnych plików? Jak stworzyć bardziej generyczne rozwiązanie.