Test database strategies in NestJS - Mini Project: Build & Apply
testDatabaseProvider that provides an in-memory database connection string with the value 'sqlite::memory:'.Use an object with provide and useValue keys to create the provider.
testDbConnection and assign it the string 'sqlite::memory:' to represent the test database connection string.Just assign the string 'sqlite::memory:' to the variable testDbConnection.
it with the description 'should connect to test database' that expects testDbConnection to equal 'sqlite::memory:'.Use Jest's it function and expect to check the connection string.
Test.createTestingModule that imports an empty array, provides testDatabaseProvider, and compile it. Assign the compiled module to a constant called module.Use await Test.createTestingModule({ imports: [], providers: [testDatabaseProvider] }).compile() and assign it to module.
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
