Skip to content

Commit 4b4ec44

Browse files
authored
Merge pull request #297 from elementar/augmented-test-utils
Patch to treat unhandled rejections as test failures
2 parents 2ab4f34 + 3886182 commit 4b4ec44

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

src/driver/express/ExpressDriver.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ export class ExpressDriver extends BaseDriver {
150150
// prepare route and route handler function
151151
const route = ActionMetadata.appendBaseRoute(this.routePrefix, actionMetadata.fullRoute);
152152
const routeHandler = function routeHandler(request: any, response: any, next: Function) {
153+
// Express calls the "get" route automatically when we call the "head" route:
154+
// Reference: https://expressjs.com/en/4x/api.html#router.METHOD
155+
// This causes a double action execution on our side, which results in an unhandled rejection,
156+
// saying: "Can't set headers after they are sent".
157+
// The following line skips action processing when the request method does not match the action method.
158+
if (request.method.toLowerCase() !== actionMetadata.type)
159+
return next();
160+
153161
return executeCallback({request, response, next});
154162
};
155163

test/functional/test-utils.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,37 @@ export function assertRequest(ports: number[],
1313

1414
ports.forEach(port => {
1515

16-
it("asserting port " + port, () => {
17-
if (args === 4) {
18-
return chakram[method](`http://127.0.0.1:${port}/${route}`).then(dataOrCallback as Function);
19-
} else if (args === 5) {
20-
return chakram[method](`http://127.0.0.1:${port}/${route}`, dataOrCallback as any).then(dataOrRequestOptionsOrCallback as Function);
21-
} else if (args === 6) {
22-
return chakram[method](`http://127.0.0.1:${port}/${route}`, dataOrCallback as any, dataOrRequestOptionsOrCallback as any).then(maybeCallback);
16+
it("asserting port " + port, async() => {
17+
let unhandledRejection: Error = undefined;
18+
const captureRejection = (e: Error) => { unhandledRejection = e; };
19+
process.on("unhandledRejection", captureRejection);
20+
21+
try {
22+
let r;
23+
if (args === 4) {
24+
r = await chakram[method](`http://127.0.0.1:${port}/${route}`).then(dataOrCallback as Function);
25+
}
26+
else if (args === 5) {
27+
r = await chakram[method](`http://127.0.0.1:${port}/${route}`, dataOrCallback as any).then(dataOrRequestOptionsOrCallback as Function);
28+
}
29+
else if (args === 6) {
30+
r = await chakram[method](`http://127.0.0.1:${port}/${route}`, dataOrCallback as any, dataOrRequestOptionsOrCallback as any).then(maybeCallback);
31+
}
32+
else {
33+
throw new Error("No assertion has been performed");
34+
}
35+
36+
if (unhandledRejection) {
37+
const e = new Error("There was an unhandled rejection while processing the request");
38+
e.stack += "\nCaused by: " + unhandledRejection.stack;
39+
throw e;
40+
}
41+
42+
return r;
43+
}
44+
finally {
45+
process.removeListener("unhandledRejection", captureRejection);
2346
}
24-
25-
throw new Error("No assertion has been performed");
2647
});
2748

2849
});

0 commit comments

Comments
 (0)