Skip to content
Plurafy

Integration Testing

Testing multiple components together

Test API endpoints, database interactions, and component integration without mocking.

Integration tests verify that multiple components work together correctly in a realistic environment.

Terminal window
npm install --save-dev supertest
const request = require('supertest');
const app = require('../app');
describe('GET /users', () => {
test('returns all users', async () => {
const response = await request(app)
.get('/users')
.expect('Content-Type', /json/)
.expect(200);
expect(response.body).toHaveProperty('users');
expect(Array.isArray(response.body.users)).toBe(true);
});
test('returns user by ID', async () => {
const response = await request(app)
.get('/users/1')
.expect(200);
expect(response.body).toHaveProperty('id', 1);
});
test('returns 404 for non-existent user', async () => {
await request(app)
.get('/users/999')
.expect(404);
});
});
describe('POST /users', () => {
test('creates new user', async () => {
const response = await request(app)
.post('/users')
.send({
name: 'John',
email: 'john@example.com'
})
.expect(201);
expect(response.body).toHaveProperty('id');
expect(response.body.name).toBe('John');
});
test('validates input', async () => {
await request(app)
.post('/users')
.send({ name: 'John' })
.expect(400);
});
});
describe('User Database', () => {
let db;
beforeAll(async () => {
db = await connectToTestDatabase();
});
afterEach(async () => {
await db.clear('users');
});
afterAll(async () => {
await db.disconnect();
});
test('creates user in database', async () => {
const user = await User.create({
name: 'John',
email: 'john@example.com'
});
const found = await User.findById(user.id);
expect(found.email).toBe('john@example.com');
});
test('updates user', async () => {
const user = await User.create({ name: 'John' });
await user.update({ name: 'Jane' });
const updated = await User.findById(user.id);
expect(updated.name).toBe('Jane');
});
});
async function createTestUser(overrides = {}) {
return User.create({
name: 'Test User',
email: 'test@example.com',
...overrides
});
}
async function seedDatabase() {
await User.create({ name: 'User 1', email: 'user1@example.com' });
await User.create({ name: 'User 2', email: 'user2@example.com' });
return User.findAll();
}
describe('User endpoints', () => {
beforeEach(async () => {
await seedDatabase();
});
test('lists users', async () => {
const response = await request(app).get('/users');
expect(response.body.users).toHaveLength(2);
});
});
test('API response structure', async () => {
const response = await request(app).get('/users/1');
expect(response.body).toMatchSnapshot({
id: expect.any(Number),
created: expect.any(String)
});
});
describe('Performance', () => {
test('returns users within 100ms', async () => {
const start = Date.now();
await request(app)
.get('/users')
.expect(200);
const duration = Date.now() - start;
expect(duration).toBeLessThan(100);
});
});
// 1. Use test database
process.env.NODE_ENV = 'test';
process.env.DATABASE_URL = 'postgresql://localhost/test_db';
// 2. Clear data between tests
afterEach(async () => {
await db.clear();
});
// 3. Test both success and failure
test('handles errors', async () => {
await request(app)
.post('/users')
.send({})
.expect(400);
});
// 4. Test side effects
test('sends email on user creation', async () => {
const sendEmailMock = jest.fn();
await request(app)
.post('/users')
.send({ name: 'John', email: 'john@example.com' })
.expect(201);
expect(sendEmailMock).toHaveBeenCalled();
});