Last active
July 16, 2019 05:48
-
-
Save radzserg/0ba19fd9596a655c5943147f589f7720 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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