Created
February 19, 2022 20:30
-
-
Save jfhector/290c7e77828eb1c60b6cbe09e1ba374a to your computer and use it in GitHub Desktop.
wrapInAsyncTryCatch
This file contains 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
Feature: wrapInAsyncTryCatch | |
Scenario: The function returned by wrapInAsyncTryCatch calls the function provided to wrapInAsyncTryCatch with the same arguments | |
Given wrapInAsyncTryCatch is called with an asynchronous function that does not throw | |
When the function returned by wrapInAsyncTryCatch is called with some arguments | |
Then the function provided to wrapInAsyncTryCatch gets called with the same arguments | |
And the function returned by wrapInAsyncTryCatch returns the same thing as the provided function | |
Scenario: It catches any error that the provided function throws | |
Given wrapInAsyncTryCatch is called with an asynchronous function that throws when called with some arguments | |
When the function returned by wrapInAsyncTryCatch is called with the same arguments | |
Then the error gets logged to the console | |
And the function returned by wrapInAsyncTryCatch does not throw |
This file contains 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
/* eslint-disable no-console */ | |
type WrapInAsyncTryCatch = { | |
<Args extends any[], ReturnType>(fn: (...args: Args) => ReturnType): ( | |
...args: Args | |
) => Promise<ReturnType | undefined>; | |
}; | |
/** | |
* Use this if you have a function that may throw an error, and you want that error handled so it doesn't propagate further. | |
* | |
* `wrapInAsyncTryCatch` is not async itself, but it expects an async function, and returns an async function. | |
* If the function you're providing is synchronous (i.e. does not return a promise), use `wrapInSynchronousTryCatch` instead. | |
* | |
* @param asyncFnToWrapInTryCatch an asynchronous function that you want called inside a try/catch block. | |
* @returns an asynchronous function which, when called, calls `fn` with the arguments it's given. `fn` will be called inside `try { ... } catch(err) { logs the err and returns }` | |
*/ | |
const wrapInAsyncTryCatch: WrapInAsyncTryCatch = asyncFnToWrapInTryCatch => { | |
return async function todoName(...args) { | |
try { | |
return await asyncFnToWrapInTryCatch(...args); | |
} catch (err) { | |
console.error(err); | |
return; | |
} | |
}; | |
}; | |
export { wrapInAsyncTryCatch }; |
This file contains 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
/* eslint-disable @typescript-eslint/no-empty-function */ | |
/* eslint-disable @typescript-eslint/no-unused-vars */ | |
/* eslint-disable no-console */ | |
import { defineFeature, loadFeature } from 'jest-cucumber'; | |
import { wrapInAsyncTryCatch } from '..'; | |
// Syncing with .feature Cucumber file | |
const feature = loadFeature('../definition.feature', { | |
loadRelativePath: true, | |
}); | |
defineFeature(feature, test => { | |
afterEach(() => { | |
jest.useRealTimers(); | |
jest.clearAllMocks(); | |
}); | |
test('The function returned by wrapInAsyncTryCatch calls the function provided to wrapInAsyncTryCatch with the same arguments', async ({ | |
given, | |
when, | |
then, | |
and, | |
}) => { | |
jest.useFakeTimers(); | |
const MOCK_RESOLVED_VALUE = 'mock_resolved_value'; | |
const functionToProvideToWithErrorBoundary = jest | |
.fn() | |
.mockResolvedValue(MOCK_RESOLVED_VALUE); | |
let functionReturnedByWithErrorBoundary: any; | |
let valueReturnedByTheFunctionReturnedByWithErrorBoundary: any; | |
given( | |
'wrapInAsyncTryCatch is called with an asynchronous function that does not throw', | |
() => { | |
functionReturnedByWithErrorBoundary = wrapInAsyncTryCatch( | |
functionToProvideToWithErrorBoundary | |
); | |
} | |
); | |
when( | |
'the function returned by wrapInAsyncTryCatch is called with some arguments', | |
async () => { | |
valueReturnedByTheFunctionReturnedByWithErrorBoundary = await functionReturnedByWithErrorBoundary( | |
'arg1', | |
'arg2' | |
); | |
} | |
); | |
then( | |
'the function provided to wrapInAsyncTryCatch gets called with the same arguments', | |
() => { | |
expect(functionToProvideToWithErrorBoundary).toHaveBeenCalledWith( | |
'arg1', | |
'arg2' | |
); | |
} | |
); | |
and( | |
'the function returned by wrapInAsyncTryCatch returns the same thing as the provided function', | |
async () => { | |
expect(valueReturnedByTheFunctionReturnedByWithErrorBoundary).toBe( | |
await functionToProvideToWithErrorBoundary('arg1', 'arg2') | |
); | |
} | |
); | |
}); | |
test('It catches any error that the provided function throws', async ({ | |
given, | |
when, | |
then, | |
and, | |
}) => { | |
const MOCK_REJECTION_REASON = 'mock_rejection_reason'; | |
const functionToProvideToWithErrorBoundary = jest | |
.fn() | |
.mockRejectedValue(MOCK_REJECTION_REASON); | |
let functionReturnedByWithErrorBoundary: any; | |
const consoleErrorSpy = jest.spyOn(console, 'error'); | |
given( | |
'wrapInAsyncTryCatch is called with an asynchronous function that throws when called with some arguments', | |
() => { | |
functionReturnedByWithErrorBoundary = wrapInAsyncTryCatch( | |
functionToProvideToWithErrorBoundary | |
); | |
} | |
); | |
when( | |
'the function returned by wrapInAsyncTryCatch is called with the same arguments', | |
async () => { | |
await functionReturnedByWithErrorBoundary(); | |
} | |
); | |
then('the error gets logged to the console', () => { | |
expect(consoleErrorSpy).toHaveBeenCalledWith(MOCK_REJECTION_REASON); | |
}); | |
and('the function returned by wrapInAsyncTryCatch does not throw', () => { | |
console.log( | |
'If this gets executed, it means there has been no unhandled exception, and this test is successful' | |
); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment