1
0
mirror of https://github.com/docker/docs.git synced 2026-10-23 18:09:02 +03:00
Files
docs/content/guides/testcontainers-nodejs-getting-started.md
Brandon Hunt 97cee42f3c docs: collapse folder+index.md guides to flat single-file guides (#25504)
## Description

Follow-up to #25338 (the guides revamp). That PR collapsed most
multi-page guide series into single pages but left ~50 guides wrapped in
a `<name>/index.md` directory structure alongside guides that are
already flat `<name>.md` files — an inconsistent mix. This PR finishes
the flattening:

- Flattens 50 folder-wrapped guides to `content/guides/<slug>.md` via
`git mv` (history preserved). These keep the same URL, since Hugo
generates the same permalink for a leaf-bundle `dir/index.md` and a flat
`dir.md`.
- Moves the last 4 guides' local per-guide image bundles
(`genai-leveraging-rag`, `genai-video-bot`, `genai-claude-code-mcp`,
`java`) into the shared `content/guides/images/` folder with
slug-prefixed filenames, matching the convention already used by most
other guides (`databases-1.webp`, `kafka-1.webp`, etc.), and rewrites
the in-body image references.
- Normalizes `genai-claude-code-mcp`'s non-standard filename
(`claude-code-mcp-guide.md`) and capitalized `Images/` folder to match
convention.
- Promotes `content/guides/frameworks/laravel/index.md` to a top-level
`content/guides/laravel.md`, since it was the only guide under
`frameworks/` and every other language/framework guide is flat.
- Adds `aliases` entries for the two URLs that actually changed
(`/guides/frameworks/laravel/` and
`/guides/genai-claude-code-mcp/claude-code-mcp-guide/`); every other
rename preserves its existing URL.

Companion PR establishing this as the documented convention going
forward: #25503

## Validation

- `hugo --minify` build via `docker compose run` completes with zero
warnings/errors (3174 pages, 1524 aliases — unchanged from before this
PR).
- Verified both changed-URL guides render at their new path and the old
path 301s via the Hugo alias redirect.
- Verified every image reference in the 4 migrated guides resolves to an
existing file in `content/guides/images/`.
- Multi-agent docs review (link-checker, cross-reference-checker,
guide-conventions) found zero issues.

## Related issues or tickets

Discussed in the team's docs Slack channel following #25338.

## Reviews

- [ ] Technical review
2026-07-09 08:45:55 -07:00

5.6 KiB

title, linkTitle, description, keywords, summary, aliases, params
title linkTitle description keywords summary aliases params
Getting started with Testcontainers for Node.js Testcontainers for Node.js Learn how to use Testcontainers for Node.js to test database interactions with a real PostgreSQL instance. testcontainers, nodejs, javascript, testing, postgresql, integration testing, jest Learn how to create a Node.js application and test database interactions using Testcontainers for Node.js with a real PostgreSQL instance.
/guides/testcontainers-nodejs-getting-started/create-project/
/guides/testcontainers-nodejs-getting-started/run-tests/
/guides/testcontainers-nodejs-getting-started/write-tests/
tags time
testing
15 minutes

In this guide, you will learn how to:

  • Create a Node.js application that stores and retrieves customers from PostgreSQL
  • Write integration tests using Testcontainers and Jest
  • Run tests against a real PostgreSQL database in a Docker container

Prerequisites

  • Node.js 18+
  • npm
  • A Docker environment supported by Testcontainers

Note

If you're new to Testcontainers, visit the Testcontainers overview to learn more about Testcontainers and the benefits of using it.

Create the Node.js project

Initialize the project

Create a new Node.js project:

$ npm init -y

Add pg, jest, and @testcontainers/postgresql as dependencies:

$ npm install pg --save
$ npm install jest @testcontainers/postgresql --save-dev

Implement the customer repository

Create src/customer-repository.js with functions to manage customers in PostgreSQL:

async function createCustomerTable(client) {
  const sql =
    "CREATE TABLE IF NOT EXISTS customers (id INT NOT NULL, name VARCHAR NOT NULL, PRIMARY KEY (id))";
  await client.query(sql);
}

async function createCustomer(client, customer) {
  const sql = "INSERT INTO customers (id, name) VALUES($1, $2)";
  await client.query(sql, [customer.id, customer.name]);
}

async function getCustomers(client) {
  const sql = "SELECT * FROM customers";
  const result = await client.query(sql);
  return result.rows;
}

module.exports = { createCustomerTable, createCustomer, getCustomers };

The module provides three functions:

  • createCustomerTable() creates the customers table if it doesn't exist.
  • createCustomer() inserts a customer record.
  • getCustomers() fetches all customer records.

Write tests with Testcontainers

Create src/customer-repository.test.js with the test:

const { Client } = require("pg");
const { PostgreSqlContainer } = require("@testcontainers/postgresql");
const {
  createCustomerTable,
  createCustomer,
  getCustomers,
} = require("./customer-repository");

describe("Customer Repository", () => {
  jest.setTimeout(60000);

  let postgresContainer;
  let postgresClient;

  beforeAll(async () => {
    postgresContainer = await new PostgreSqlContainer().start();
    postgresClient = new Client({
      connectionString: postgresContainer.getConnectionUri(),
    });
    await postgresClient.connect();
    await createCustomerTable(postgresClient);
  });

  afterAll(async () => {
    await postgresClient.end();
    await postgresContainer.stop();
  });

  it("should create and return multiple customers", async () => {
    const customer1 = { id: 1, name: "John Doe" };
    const customer2 = { id: 2, name: "Jane Doe" };

    await createCustomer(postgresClient, customer1);
    await createCustomer(postgresClient, customer2);

    const customers = await getCustomers(postgresClient);
    expect(customers).toEqual([customer1, customer2]);
  });
});

Here's what the test does:

  • The beforeAll block starts a real PostgreSQL container using PostgreSqlContainer. It then creates a pg client connected to the container and sets up the customers table.
  • The afterAll block closes the client connection and stops the container.
  • The test inserts two customers, fetches all customers, and asserts the results match.

The test timeout is set to 60 seconds to allow time for the container to start on the first run (when the Docker image needs to be pulled).

Run tests and next steps

Run the tests

Add the test script to package.json if it isn't there already:

{
  "scripts": {
    "test": "jest"
  }
}

Then run the tests:

$ npm test

You should see output like:

 PASS  src/customer-repository.test.js
  Customer Repository
    ✓ should create and return multiple customers (5 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total

To see what Testcontainers is doing under the hood — which containers it starts, what versions it uses — set the DEBUG environment variable:

$ DEBUG=testcontainers* npm test

Summary

The Testcontainers for Node.js library helps you write integration tests using the same type of database (Postgres) that you use in production, instead of mocks. Because you aren't using mocks and instead talk to real services, you're free to refactor code and still verify that the application works as expected.

In addition to PostgreSQL, Testcontainers provides dedicated modules for many SQL databases, NoSQL databases, messaging queues, and more.

To learn more about Testcontainers, visit the Testcontainers overview.

Further reading