What if your tests could run anywhere, anytime, without breaking your real data?
Why Test database strategies in NestJS? - Purpose & Use Cases
Imagine running your NestJS app tests against the same database your app uses in production.
Every test changes data, and you have to clean up manually before the next test runs.
Manually managing test data is slow and risky.
Tests can interfere with each other, causing unpredictable failures.
It's hard to keep the database clean and consistent for every test run.
Test database strategies provide isolated, fresh databases or controlled environments for each test.
This keeps tests independent, fast, and reliable without manual cleanup.
run tests on production DB; manually delete test data after each test
use in-memory DB or test containers; auto-reset DB state before each test
Reliable and fast automated tests that can run anytime without risking real data.
Using a test database strategy, you can run hundreds of NestJS tests in parallel without conflicts or leftover data.
Manual test data handling is error-prone and slow.
Test database strategies isolate tests for reliability.
This leads to faster, safer, and more maintainable testing.
Practice
Why do we use a separate test database in NestJS applications?
Solution
Step 1: Understand the purpose of test databases
Test databases are used to isolate testing data from real data to prevent accidental data loss or corruption.Step 2: Identify the main reason for using test databases in NestJS
Using a separate test database ensures tests do not affect production data, keeping it safe.Final Answer:
To keep real data safe and avoid accidental changes during tests -> Option BQuick Check:
Test database = Protect real data [OK]
- Thinking test DB improves production speed
- Confusing test DB with security for passwords
- Assuming test DB reduces main DB size
Which of the following is the correct way to configure an in-memory SQLite database for testing in a NestJS TypeOrmModule?
TypeOrmModule.forRoot({
type: 'sqlite',
database: ???,
entities: [User],
synchronize: true,
})Solution
Step 1: Recall SQLite in-memory database syntax
SQLite uses ':memory:' as the special name to create a temporary in-memory database.Step 2: Match the correct database name in the config
Using ':memory:' tells TypeORM to use an in-memory DB for fast, isolated tests.Final Answer:
':memory:' -> Option DQuick Check:
SQLite in-memory DB = ':memory:' [OK]
- Using a file name instead of ':memory:'
- Confusing ':disk:' as valid SQLite option
- Using arbitrary file names like 'memory.db'
Given this NestJS test setup snippet, what will be the output of console.log(users.length) inside the test?
beforeEach(async () => {
await connection.synchronize(true); // resets DB
await userRepository.save([{ name: 'Alice' }, { name: 'Bob' }]);
});
test('users count', async () => {
const users = await userRepository.find();
console.log(users.length);
});Solution
Step 1: Understand what synchronize(true) does
Calling synchronize(true) resets the database, clearing all data before each test.Step 2: Analyze the data saved before the test
After reset, two users 'Alice' and 'Bob' are saved, so the DB has 2 users.Step 3: Check the find() result
Finding all users returns an array of length 2.Final Answer:
2 -> Option CQuick Check:
Reset + save 2 users = 2 users found [OK]
- Assuming DB is not reset and counting old data
- Thinking synchronize(true) deletes data after save
- Expecting undefined because of async confusion
What is the main problem with this test database setup code snippet?
beforeAll(async () => {
await connection.synchronize(true);
});
afterAll(async () => {
await connection.close();
});
test('should save user', async () => {
await userRepository.save({ name: 'Charlie' });
const users = await userRepository.find();
expect(users.length).toBe(1);
});
test('should find no users initially', async () => {
const users = await userRepository.find();
expect(users.length).toBe(0);
});Solution
Step 1: Analyze when the database reset happens
Database reset with synchronize(true) is done only once before all tests, not before each test.Step 2: Understand test data persistence
Data saved in the first test remains in the DB during the second test, causing unexpected results.Final Answer:
Database is reset only once before all tests, causing data to persist between tests -> Option AQuick Check:
Reset once beforeAll causes data carryover [OK]
- Thinking connection closes too early
- Assuming userRepository is undefined
- Believing tests run in parallel causing race
You want to ensure each test in your NestJS app runs with a clean database state using an in-memory SQLite DB. Which strategy best achieves this?
- Use
TypeOrmModule.forRootwithdatabase: ':memory:' - Reset the database schema before each test
- Close and reopen the connection before each test
- Seed only required test data inside each test
Which combination of these steps is best practice?
Solution
Step 1: Use in-memory DB for fast isolated tests
Setting database to ':memory:' creates a fresh DB in memory for each connection.Step 2: Reset schema before each test
Resetting schema ensures no leftover data or schema changes affect tests.Step 3: Close and reopen connection before each test
Reopening connection resets the in-memory DB state fully.Step 4: Seed only needed data per test
Seeding minimal data keeps tests independent and fast.Final Answer:
All steps 1, 2, 3, and 4 -> Option AQuick Check:
Full reset + seed per test = reliable tests [OK]
- Skipping connection reopen causing stale DB
- Not resetting schema before tests
- Seeding too much data globally
Ready to prove it?
Pass the test and this pattern moves unknown
