Bird
Raised Fist0
Node.jsframework~20 mins

Integration testing patterns in Node.js - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Integration 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 integration test snippet?
Consider this Node.js integration test using Jest and Supertest. What will be the test result output?
Node.js
import request from 'supertest';
import app from './app';

test('GET /users returns 2 users', async () => {
  const response = await request(app).get('/users');
  expect(response.status).toBe(200);
  expect(response.body.length).toBe(2);
});
ATest passes because the /users endpoint returns exactly 2 users with status 200.
BTest fails because response.status is not 200.
CTest fails because response.body.length is not 2.
DTest throws an error because app is not imported correctly.
Attempts:
2 left
💡 Hint
Check what the test expects and what the endpoint returns.
❓ lifecycle
intermediate
1:30remaining
Which lifecycle hook is best for setting up a database connection before integration tests?
In a Node.js integration test suite using Jest, which lifecycle method should you use to open a database connection before all tests run?
AbeforeEach()
BafterEach()
CafterAll()
DbeforeAll()
Attempts:
2 left
💡 Hint
Think about a setup that runs once before all tests.
🔧 Debug
advanced
2:30remaining
Why does this integration test fail with a timeout?
Look at this test code snippet. Why does it fail with a timeout error?
Node.js
test('POST /login returns 200', async () => {
  const response = await request(app).post('/login').send({ username: 'user', password: 'pass' });
  expect(response.status).toBe(200);
});
AThe app server is not closed after previous tests, causing port conflicts and hanging requests.
BThe test is missing a done callback to signal completion.
CThe request is missing headers, so the server never responds.
DThe test uses async/await incorrectly, causing the promise to never resolve.
Attempts:
2 left
💡 Hint
Consider what happens if the server is not properly closed between tests.
📝 Syntax
advanced
2:30remaining
Which option correctly mocks a database call in an integration test?
You want to mock the database call getUserById in your integration test. Which code snippet correctly mocks it using Jest?
Node.js
import * as db from './db';

jest.mock('./db');

// Your test here
Adb.getUserById = jest.fn(() => ({ id: 1, name: 'Alice' }));
Bjest.mockResolvedValue(db.getUserById, { id: 1, name: 'Alice' });
Cdb.getUserById.mockResolvedValue({ id: 1, name: 'Alice' });
Djest.fn(db.getUserById).mockReturnValue({ id: 1, name: 'Alice' });
Attempts:
2 left
💡 Hint
Check how to mock a function's resolved value with Jest.
❓ state_output
expert
3:00remaining
What is the final value of 'count' after running this integration test sequence?
Given this test suite that modifies a shared state, what is the final value of the variable 'count' after all tests run?
Node.js
let count = 0;

describe('Counter tests', () => {
  beforeAll(() => { count = 5; });

  test('Increment count', () => {
    count += 3;
    expect(count).toBe(8);
  });

  test('Decrement count', () => {
    count -= 2;
    expect(count).toBe(6);
  });

  afterAll(() => {
    count += 1;
  });
});
A9
B7
C6
D8
Attempts:
2 left
💡 Hint
Follow the changes to 'count' step by step through the lifecycle hooks and tests.

Practice

(1/5)
1. What is the main goal of integration testing in a Node.js application?
easy
A. To check the syntax of the code
B. To test individual functions in isolation
C. To verify that different parts of the app work together correctly
D. To measure the app's performance under load

Solution

  1. Step 1: Understand integration testing purpose

    Integration testing focuses on checking if multiple parts of the app interact correctly, not just individual pieces.
  2. Step 2: Compare with other testing types

    Syntax checking is done by linters, unit tests check single functions, and performance tests measure speed, so these are not integration tests.
  3. Final Answer:

    To verify that different parts of the app work together correctly -> Option C
  4. Quick Check:

    Integration testing = check parts working together [OK]
Hint: Integration tests check combined parts, not single functions [OK]
Common Mistakes:
  • Confusing integration tests with unit tests
  • Thinking integration tests check code syntax
  • Mixing integration tests with performance testing
2. Which of the following is the correct way to define a setup hook in a Node.js integration test using Mocha?
easy
A. init(() => { /* setup code */ })
B. setup(() => { /* setup code */ })
C. start(() => { /* setup code */ })
D. beforeEach(() => { /* setup code */ })

Solution

  1. Step 1: Recall Mocha setup hooks

    Mocha uses beforeEach and before hooks to run setup code before tests.
  2. Step 2: Identify correct syntax

    Only beforeEach is a valid Mocha hook; setup, init, and start are not Mocha functions.
  3. Final Answer:

    beforeEach(() => { /* setup code */ }) -> Option D
  4. Quick Check:

    Mocha setup hook = beforeEach [OK]
Hint: Mocha uses beforeEach for setup, not setup or init [OK]
Common Mistakes:
  • Using non-existent hook names like setup or init
  • Confusing beforeEach with afterEach
  • Forgetting arrow function syntax
3. Consider this Node.js integration test snippet using Jest and Supertest:
test('GET /users returns 200', async () => {
  const response = await request(app).get('/users');
  expect(response.statusCode).toBe(200);
});

What does this test check?
medium
A. That the /users endpoint returns a JSON array
B. That the /users endpoint returns a 200 status code
C. That the app throws an error on /users
D. That the /users endpoint is unreachable

Solution

  1. Step 1: Analyze the test code

    The test sends a GET request to '/users' and checks the response status code.
  2. Step 2: Understand the assertion

    The assertion expects the status code to be 200, meaning success.
  3. Final Answer:

    That the /users endpoint returns a 200 status code -> Option B
  4. Quick Check:

    Response status 200 means success [OK]
Hint: Check what the expect() function tests in the code [OK]
Common Mistakes:
  • Assuming it checks response body instead of status
  • Thinking it tests error or unreachable endpoint
  • Ignoring async/await usage
4. You wrote this integration test using Jest:
beforeAll(() => {
  db.connect();
});

test('fetch data', async () => {
  const data = await db.getData();
  expect(data).toBeDefined();
});

afterAll(() => {
  db.disconnect();
});

But the test fails because the database connection is not ready. What is the likely problem?
medium
A. beforeAll should be async and await db.connect()
B. afterAll should run before the test
C. db.getData() should not be awaited
D. expect(data).toBeDefined() is incorrect syntax

Solution

  1. Step 1: Check async setup in beforeAll

    Database connection is asynchronous, so beforeAll must be async and await db.connect() to ensure readiness.
  2. Step 2: Verify other parts

    afterAll runs after tests, awaiting db.getData() is correct, and expect syntax is valid.
  3. Final Answer:

    beforeAll should be async and await db.connect() -> Option A
  4. Quick Check:

    Async setup needs await in beforeAll [OK]
Hint: Async setup needs await in beforeAll hook [OK]
Common Mistakes:
  • Not making beforeAll async for async setup
  • Misplacing afterAll before tests
  • Ignoring await on async calls
5. You want to write an integration test for a Node.js app that creates a user via POST /users and then fetches it via GET /users/:id. Which pattern best ensures your test is reliable and isolated?
hard
A. Use setup hook to create a test user, then test GET /users/:id, and cleanup hook to delete the user
B. Run both POST and GET requests in the same test without cleanup
C. Only test GET /users/:id assuming user exists in database
D. Manually add user in database before tests and never delete

Solution

  1. Step 1: Understand test isolation

    Tests should not depend on external data; setup creates needed data, cleanup removes it.
  2. Step 2: Apply setup and cleanup hooks

    Creating a user in setup, testing GET, then deleting user in cleanup keeps tests reliable and repeatable.
  3. Final Answer:

    Use setup hook to create a test user, then test GET /users/:id, and cleanup hook to delete the user -> Option A
  4. Quick Check:

    Setup and cleanup keep tests isolated and reliable [OK]
Hint: Setup and cleanup hooks keep tests clean and repeatable [OK]
Common Mistakes:
  • Not cleaning up test data causing flaky tests
  • Assuming data exists without setup
  • Combining unrelated tests without isolation
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