As I was writing unit tests for my codebase, I noticed that I kept duplicating the code responsible for making HTTP requests and setting expectations for the response. To avoid this redundancy, I created some helper functions, one of which is called expectedResponseForGET
. This function is static and resides within a TestUtils
class in a file named utils.ts
.
In certain test cases, I utilize the expectedResponseForGET
method multiple times to verify different aspects following a POST request. However, when an expectation fails (i.e., the response does not match the expected outcome), the test fails, and the call stack only displays the failed expectation from the expectedResponseForGET
function without indicating which test initially triggered the helper function.
The stack trace provided for the failed expectation typically looks like this:
src/tests/sites/add.test.ts
Add site route
✓ User4 - Add site, not company manager (238 ms)
✕ User1 - Add site, company manager (269 ms)
● Add site route › User1 - Add site, company manager
expect(received).toEqual(expected) // deep equality
- Expected - 1
+ Received + 1
@@ -1,63 +1,10 @@
- "location": "Location2",
+ "location": "Location",
92 | .set('Authorization', user.token);
93 | expect(res.status).toBe(200);
> 94 | expect(res.body).toEqual(response);
| ^
95 | return res;
96 | };
97 |
at src/tests/utils.ts:94:22
at fulfilled (src/tests/utils.ts:5:58)
This portion contains details related to the line with the failed expectation and the import of 'request' from Supertest, but it lacks information about the specific test from src/tests/sites/add.test.ts
that invoked expectedResponseForGET
.
Below is the test scenario in question:
test(' User1 - Add site, company manager', async () => {
await TestUtils.expectedResponseForPOST(
server,
C1.users.U1,
route,
C1.sites.S5.requests.addSite,
C1.sites.S5.responses.fullSite,
);
await TestUtils.expectedResponseForGET(
server,
C1.users.U1,
routeSites,
C1.sites.responses.allAfterS5,
);
await TestUtils.expectedResponseForGET(
server,
C1.users.U1,
routeWork,
C1.work.responses.allAfterS5,
);
});
Here are the definitions of the helper functions:
import request from 'supertest';
class TestUtils{
static expectedResponseForGET = async (
server: Express,
user: UserTest,
route: string,
response: GenericResponse,
) => {
const res = await request(server)
.get(route)
.set('Authorization', user.token);
expect(res.status).toBe(200);
expect(res.body).toEqual(response);
return res;
};
static expectedResponseForPOST = async (
server: Express,
user: UserTest,
route: string,
// eslint-disable-next-line @typescript-eslint/ban-types
req: Object,
response: GenericResponse,
) => {
const res = await request(server)
.post(route)
.send(req)
.set('Authorization', user.token);
expect(res.status).toBe(200);
expect(res.body).toEqual(response);
return res;
};
}
If anyone has encountered similar challenges and found a solution or workaround to display the test line that invoked the helper method, please share your insights.