Completing API Test Suite
In my previous post, I set up our testing environment and implemented tests for the POST /words endpoint. Now, let's continue our journey by implementing tests for the remaining endpoints. This will complete our test suite and ensure comprehensive coverage of our Word API. 🧪🚀
GET /words Endpoint
Let's start with the endpoint that retrieves all words:
describe('GET /words', () => {
it('should return all words', async () => {
const mockWords = [{ id: 1, word: 'Hello' }, { id: 2, word: 'World' }];
pool.query.mockResolvedValueOnce({ rows: mockWords });
const res = await request(app).get('/words');
expect(res.statusCode).toBe(200);
expect(res.body).toEqual(mockWords);
});
it('should handle empty word list', async () => {
pool.query.mockResolvedValueOnce({ rows: [] });
const res = await request(app).get('/words');
expect(res.statusCode).toBe(200);
expect(res.body).toEqual([]);
});
it('should return 500 if an unexpected error occurs', async () => {
pool.query.mockRejectedValueOnce(new Error('Database error'));
const res = await request(app).get('/words');
expect(res.statusCode).toBe(500);
expect(res.body).toEqual({ message: 'Internal Server Error' });
});
});
GET /words/:id Endpoint
Now, let's test retrieving a specific word:
describe('GET /words/:id', () => {
it('should return a specific word', async () => {
const mockWord = { id: 1, word: 'Test' };
pool.query.mockResolvedValueOnce({ rows: [mockWord] });
const res = await request(app).get('/words/1');
expect(res.statusCode).toBe(200);
expect(res.body).toEqual(mockWord);
});
it('should return 404 for non-existent ID', async () => {
pool.query.mockResolvedValueOnce({ rows: [] });
const res = await request(app).get('/words/999');
expect(res.statusCode).toBe(404);
expect(res.body).toEqual({ message: 'Word not found' });
});
it('should return 400 for invalid ID format', async () => {
const res = await request(app).get('/words/invalid');
expect(res.statusCode).toBe(400);
expect(res.body).toEqual({ message: 'Invalid word ID' });
});
});
PUT /words/:id Endpoint
Let's test updating an existing word:
describe('PUT /words/:id', () => {
it('should update an existing word successfully', async () => {
const updatedWord = { id: 1, word: 'Updated' };
pool.query.mockResolvedValueOnce({ rows: [updatedWord] });
const res = await request(app)
.put('/words/1')
.send({ word: 'Updated' });
expect(res.statusCode).toBe(200);
expect(res.body).toEqual(updatedWord);
});
it('should return 404 if word ID doesn't exist', async () => {
pool.query.mockResolvedValueOnce({ rows: [] });
const res = await request(app)
.put('/words/999')
.send({ word: 'Updated' });
expect(res.statusCode).toBe(404);
expect(res.body).toEqual({ message: 'Word not found' });
});
it('should return 400 if word is missing from request body', async () => {
const res = await request(app)
.put('/words/1')
.send({});
expect(res.statusCode).toBe(400);
expect(res.body).toEqual({ message: 'Word is required' });
});
});
DELETE /words/:id Endpoint
Finally, let's test deleting a word:
describe('DELETE /words/:id', () => {
it('should delete an existing word successfully', async () => {
pool.query.mockResolvedValueOnce({ rows: [{ id: 1 }] });
const res = await request(app).delete('/words/1');
expect(res.statusCode).toBe(200);
expect(res.body).toEqual({ message: 'Word deleted successfully' });
});
it('should return 404 if word ID doesn't exist', async () => {
pool.query.mockResolvedValueOnce({ rows: [] });
const res = await request(app).delete('/words/999');
expect(res.statusCode).toBe(404);
expect(res.body).toEqual({ message: 'Word not found' });
});
});
Ensuring Consistency
As I implemented these tests, I made sure to maintain consistency in error messages and status codes across all endpoints. This consistency is crucial for creating a predictable and user-friendly API.
Key Takeaways
Running these tests gives me confidence in the reliability and correctness of our Word API endpoints. As we add new features or modify existing ones, we'll need to update and expand our test suite accordingly.
Next Steps
With our Word API endpoints thoroughly tested, our next challenge will be implementing and testing the translation endpoints. This will involve applying everything we've learned so far while dealing with the added complexity of related data.
I'm excited to continue this journey of building a well-tested, robust API for our language learning app. Stay tuned for our next adventure in test-driven development! 🚀📚
#sofwaretesting #jest #apitesting #testdrivendevelopment