Bird
Raised Fist0
Node.jsframework~20 mins

Testing async code in Node.js - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Async Testing Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What is the output of this async test with Jest?
Consider this Jest test code that tests an async function. What will the test output be?
Node.js
test('async test with done callback', done => {
  setTimeout(() => {
    expect(2 + 2).toBe(4);
    done();
  }, 100);
});
AThe test times out because done() is never called.
BThe test fails immediately due to missing await.
CThe test passes after 100ms delay.
DThe test throws a syntax error.
Attempts:
2 left
💡 Hint
Look at how done() is used to signal test completion.
📝 Syntax
intermediate
2:00remaining
Which option correctly tests an async function returning a promise in Jest?
You want to test this async function that returns a promise. Which test code is correct?
Node.js
async function fetchData() {
  return 'data';
}
A
test('fetchData returns data', async () => {
  const data = await fetchData();
  expect(data).toBe('data');
});
B
test('fetchData returns data', () => {
  const data = fetchData();
  expect(data).toBe('data');
});
C
test('fetchData returns data', () => {
  return fetchData().then(data => {
    expect(data).toBe('data');
  });
});
D
test('fetchData returns data', () => {
  expect(fetchData()).toBe('data');
});
Attempts:
2 left
💡 Hint
Remember to await the promise or return it for Jest to handle async.
🔧 Debug
advanced
2:00remaining
Why does this Jest async test fail with a timeout?
Examine this test code. Why does Jest report a timeout error?
Node.js
test('async test missing return', () => {
  fetchData().then(data => {
    expect(data).toBe('data');
  });
});

async function fetchData() {
  return 'data';
}
ABecause the test function is marked async but does not await.
BBecause fetchData throws an error that is not caught.
CBecause expect is used incorrectly inside then.
DBecause the test function does not return the promise, Jest does not wait for it.
Attempts:
2 left
💡 Hint
Jest needs to know when async work finishes.
❓ state_output
advanced
2:00remaining
What is the value of count after this async test runs?
Given this code, what is the final value of count after the test completes?
Node.js
let count = 0;

function incrementAsync() {
  return new Promise(resolve => {
    setTimeout(() => {
      count += 1;
      resolve(count);
    }, 50);
  });
}

test('incrementAsync increments count', async () => {
  await incrementAsync();
  await incrementAsync();
});
Acount is undefined
Bcount is 2
Ccount is 0
Dcount is 1
Attempts:
2 left
💡 Hint
Each call increments count by 1 after 50ms.
🧠 Conceptual
expert
3:00remaining
Which Jest test pattern ensures proper async error handling?
You want to test that an async function throws an error. Which test pattern correctly catches the error?
Node.js
async function failAsync() {
  throw new Error('fail');
}
A
test('failAsync throws', async () => {
  await expect(failAsync()).rejects.toThrow('fail');
});
B
test('failAsync throws', async () => {
  try {
    await failAsync();
  } catch (e) {
    expect(e.message).toBe('fail');
  }
});
C
test('failAsync throws', () => {
  expect(() => failAsync()).toThrow('fail');
});
D
test('failAsync throws', () => {
  return failAsync().catch(e => {
    expect(e.message).toBe('fail');
  });
});
Attempts:
2 left
💡 Hint
Use Jest's rejects matcher for promises that throw.

Practice

(1/5)
1. What is the main reason to use async and await in Node.js tests?
easy
A. To make the test run faster by skipping waits
B. To automatically retry failed tests
C. To wait for asynchronous code to finish before checking results
D. To convert synchronous code into asynchronous code

Solution

  1. Step 1: Understand async behavior in tests

    Async code runs in the background, so tests must wait for it to finish to check results correctly.
  2. Step 2: Role of async/await in tests

    Using async/await pauses the test until the async code completes, ensuring accurate result checking.
  3. Final Answer:

    To wait for asynchronous code to finish before checking results -> Option C
  4. Quick Check:

    async/await waits for async code [OK]
Hint: Async tests must wait for completion before assertions [OK]
Common Mistakes:
  • Thinking async/await speeds up tests
  • Ignoring async code completion before assertions
  • Confusing async/await with retries
2. Which of the following is the correct syntax to write an async test function in Node.js using Jest?
easy
A. test('example', () => { await asyncFunc(); });
B. async test('example', () => { asyncFunc(); });
C. test async('example', () => { asyncFunc(); });
D. test('example', async () => { await asyncFunc(); });

Solution

  1. Step 1: Identify correct async test syntax

    Jest requires the test callback to be marked async to use await inside it.
  2. Step 2: Check each option

    test('example', async () => { await asyncFunc(); }); correctly marks the callback async and uses await inside. Others either miss async or misuse syntax.
  3. Final Answer:

    test('example', async () => { await asyncFunc(); }); -> Option D
  4. Quick Check:

    async keyword before test callback [OK]
Hint: Async test functions need async keyword before callback [OK]
Common Mistakes:
  • Omitting async keyword on test callback
  • Using await outside async function
  • Incorrect placement of async keyword
3. Consider this test code snippet:
test('fetch data returns correct value', async () => {
  const data = await fetchData();
  expect(data).toBe('hello');
});

What happens if fetchData() returns a promise resolving to 'hello'?
medium
A. The test fails because await is missing
B. The test passes because data matches 'hello'
C. The test throws a syntax error
D. The test never finishes because of missing done()

Solution

  1. Step 1: Analyze async test behavior

    The test awaits fetchData(), so data gets the resolved value 'hello'.
  2. Step 2: Check assertion correctness

    expect(data).toBe('hello') matches the resolved value, so the test passes.
  3. Final Answer:

    The test passes because data matches 'hello' -> Option B
  4. Quick Check:

    await resolves promise, expect matches value [OK]
Hint: Await resolves promise before expect check [OK]
Common Mistakes:
  • Forgetting await causing test to fail
  • Confusing syntax error with runtime error
  • Thinking done() is needed with async/await
4. What is wrong with this async test code?
test('async error test', async () => {
  try {
    await asyncFunc();
  } catch (e) {
    expect(e.message).toBe('fail');
  }
});
medium
A. The test passes even if asyncFunc does not throw an error
B. The test syntax is invalid
C. The catch block will never run
D. The test needs done() callback

Solution

  1. Step 1: Understand test behavior on no error

    If asyncFunc() does not throw, the catch block is skipped and no assertion runs.
  2. Step 2: Consequence of missing assertion on success

    Test passes silently even if error was expected, missing failure detection.
  3. Final Answer:

    The test passes even if asyncFunc does not throw an error -> Option A
  4. Quick Check:

    Missing assertion outside catch causes false pass [OK]
Hint: Always assert outside catch to catch missing errors [OK]
Common Mistakes:
  • Assuming catch always runs
  • Not failing test if no error thrown
  • Using done() unnecessarily with async/await
5. You want to test an async function getUser(id) that returns user data or throws if user not found. Which test correctly checks both success and error cases?
hard
A. test('user found', async () => { const user = await getUser(1); expect(user.name).toBe('Alice'); }); test('user not found', async () => { try { await getUser(999); expect(true).toBe(false); } catch (e) { expect(e.message).toBe('not found'); } });
B. test('user found', () => { getUser(1).then(user => { expect(user.name).toBe('Alice'); }); }); test('user not found', () => { getUser(999).catch(e => { expect(e.message).toBe('not found'); }); });
C. test('user found', async () => { const user = getUser(1); expect(user.name).toBe('Alice'); }); test('user not found', async () => { try { await getUser(999); } catch (e) { expect(e.message).toBe('not found'); } });
D. test('user found', async () => { const user = await getUser(1); expect(user.name).toBe('Alice'); }); test('user not found', async () => { expect(await getUser(999)).toThrow('not found'); });

Solution

  1. Step 1: Check success test correctness

    Options A and D await getUser(1) and check user.name correctly. test('user found', async () => { const user = getUser(1); expect(user.name).toBe('Alice'); }); test('user not found', async () => { try { await getUser(999); } catch (e) { expect(e.message).toBe('not found'); } }); misses await, so user is a promise with no name property. test('user found', () => { getUser(1).then(user => { expect(user.name).toBe('Alice'); }); }); test('user not found', () => { getUser(999).catch(e => { expect(e.message).toBe('not found'); }); }); uses .then without async test function, risking timing issues.
  2. Step 2: Check error test correctness

    test('user found', async () => { const user = await getUser(1); expect(user.name).toBe('Alice'); }); test('user not found', async () => { try { await getUser(999); expect(true).toBe(false); } catch (e) { expect(e.message).toBe('not found'); } }); correctly fails test if no error thrown by asserting false after await. test('user found', async () => { const user = await getUser(1); expect(user.name).toBe('Alice'); }); test('user not found', async () => { expect(await getUser(999)).toThrow('not found'); }); incorrectly awaits before expect.toThrow: rejection throws synchronously before expect runs; resolution uses wrong matcher on user object. test('user found', async () => { const user = getUser(1); expect(user.name).toBe('Alice'); }); test('user not found', async () => { try { await getUser(999); } catch (e) { expect(e.message).toBe('not found'); } }); misses failing test if no error thrown. test('user found', () => { getUser(1).then(user => { expect(user.name).toBe('Alice'); }); }); test('user not found', () => { getUser(999).catch(e => { expect(e.message).toBe('not found'); }); }); uses catch but no async/await, risking false positives.
  3. Final Answer:

    Uses try { await getUser(999); expect(true).toBe(false); } catch (e) { expect(e.message).toBe('not found'); } -> Option A
  4. Quick Check:

    Fail test if no error thrown in catch [OK]
Hint: Fail test explicitly if expected error is not thrown [OK]
Common Mistakes:
  • Not awaiting promises in tests
  • Missing failure assertion if no error thrown
  • Using then/catch without async/await in Jest
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard