Awaiting Promises
Run locally for transcripts
I will start by making the
test()
function in setup.ts
asynchronous.globalThis.test = async function (title, callback) {
This will allow me to await the
callback()
if it happens to be async
too.globalThis.test = async function (title, callback) {
try {
await callback()
console.log(`β ${title}`)
} catch (error) {
callback
is now, potentially, an asynchronous function, I will adjust its return type to include Promise<void>
:declare global {
var expect: (actual: unknown) => Assertions
var test: (title: string, callback: () => void | Promise<void>) => void
var beforeAll: (callback: () => void) => void
var afterAll: (callback: () => void) => void
}
If I run the tests now, I can correctly see the assertion on
greetByResponse()
failing the relevant test:β returns a greeting message for the given name
β returns a congratulation message for the given name
β returns a greeting message for the given user response
Error: Expected Hello, undefined! Happy, Monday. to equal to Hello, Patrick! Happy, Monday.
The rejected assertion message mentions
undefined
instead of the user's first name. If I take a look at the mocked response, it has the { name: string }
structure while the greetByResponse()
function expects the response shape to be { firstName: string }
. The keys for the first name don't match! But who's right hereβthe test or the tested code?In the previous exercises, you've learned that you should always treat test assertions as the source of truth. In this case, however, the assertion itself has nothing to do with the actual problem:
test('returns a greeting message for the given user response', async () => {
const response = Response.json({ name: 'Patrick' })
expect(await greetByResponse(response)).toBe('Hello, Patrick! Happy, Monday.')
})
Instead, the root of the problem is in how we've constructed the mocked response in the test. I will resolve the issue by making sure that the mocked response I've prepared matched in shape to the one expected by the
greetByResponse()
function.test('returns a greeting message for the given user response', async () => {
const response = Response.json({ name: 'Patrick' })
const response = Response.json({ firstName: 'Patrick' })
expect(await greetByResponse(response)).toBe('Hello, Patrick! Happy, Monday.')
})
With the fix in place, I re-run the tests to see them all pass:
npx tsx --import ./setup.ts greet.test.ts
β returns a greeting message for the given name
β returns a congratulation message for the given name
β returns a greeting message for the given user response