Skip to content

Instantly share code, notes, and snippets.

@radzserg
Last active July 16, 2019 05:48
Show Gist options
  • Select an option

  • Save radzserg/0ba19fd9596a655c5943147f589f7720 to your computer and use it in GitHub Desktop.

Select an option

Save radzserg/0ba19fd9596a655c5943147f589f7720 to your computer and use it in GitHub Desktop.
import backendApi from "./path/to/backendApi";
import history from "./path/to/configureHistory";
export function* saveProduct(
action: ISaveProductAction
) {
const productResult = backendApi.saveProduct(action.productId, action.productData);
yield put(saveUserDetails(userDetails));
history.push("/products");
return true;
}
// approach #1 - integration testing
// in that case we rely on real backend API and will test response from it
// it takes more time and resources
// you should have some TESTING backend for this
it("saves product", () => {
const productData = {... };
const action: ISaveProduct = {
type: SAVE_PRODUCT,
productData,
};
const gen = saveProduct(action);
const next = gen.next();
assert.deepEqual(
gen.next().value,
saveUserDetails({success: true, ... rest of the response we can check})
);
// how to test history.push is still an open question
expect(next.done).toBeTruthy();
});
// approach #2 - rely on NODE_ENV and replace
// backendApi.ts, we will provide stub data in
// the response that we can test in the test
// bad thing is we mix production code with testing mocks!
if (NODE_ENV === "testing") {
const mockedVersion = {
saveUserDetails: jest.fn().mockReturnValue({success: true}),
}
return mockedVersion;
}
return productionVersion;
// can do pretty same for configureHistory.ts
// but history.push does not return anything, so we cannot rely on response
// and how do you pass mocked version into the test itself :) ?
if (NODE_ENV === "testing") {
const mockedHistory = {
const history = ({
push: jest.fn()
} as any) as History;
};
}
return createBrowserHistory();
// alternatively can use jest.spyOn, but still we need to rely on NODE_ENV
it("saves product", () => {
const productData = {... };
const action: ISaveProduct = {
type: SAVE_PRODUCT,
productData,
};
const gen = saveParticipantsQuantity(action);
const next = gen.next();
assert.deepEqual(
gen.next().value,
saveUserDetails({success: true}) // rely on a test data from mocked version
);
// expect(history.mock.calls[0][0]).toEqual(expectedUrl); // how can I pass history
expect(next.done).toBeTruthy();
});
// approach #3
// after all we can pass dependencies as arguments
// but ideologically it's not right and this approach
// will bring us another issue since right now we have to keep all deps in
// our react components
export function* saveProduct(
action: ISaveProductAction
) {
const {history, backendApi} = action;
const productResult = backendApi.saveProduct(action.productId, action.productData);
yield put(saveUserDetails(userDetails));
history.push("/products");
return true;
}
it("saves product", () => {
const push = jest.fn();
const historyMock = ({ push } as unknown) as History;
const saveProduct = jest.fn().mockReturnValue({success: true});
const backendApi = ({ saveProduct } as unknown) as IBackendApi;
const productData = {... };
const action: ISaveProduct = {
type: SAVE_PRODUCT,
productData,
history,
backendApi
};
const gen = saveParticipantsQuantity(action);
const next = gen.next();
assert.deepEqual(
gen.next().value,
saveUserDetails({success: true}) // rely on a test data that we pass a few lines above
);
expect(push).toHaveBeenCalledWith("/products");
expect(next.done).toBeTruthy();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment