Imported from mostafaelbesh/med-rag (
.claude/skills/api-testing/SKILL.md). Install upstream withnpx skills add mostafaelbesh/med-rag --skill api-testing. Copyright stays with the author.
Backend Testing Conventions
Rules
- Every service file has a corresponding
.spec.tsinserver/tests/ - Mock external APIs (openFDA, RxNorm) — never hit real APIs in tests
- Use jest.mock() for module mocking
- Use supertest for HTTP endpoint testing
- Test both success and error paths
- Mock ChromaDB responses for retrieval tests
Mocking External APIs
import axios from 'axios';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
mockedAxios.get.mockResolvedValue({
data: { results: [{ /* mock FDA label */ }] }
});
Test Structure
describe('ServiceName', () => {
describe('methodName', () => {
it('should handle valid input', async () => { /* ... */ });
it('should handle missing data gracefully', async () => { /* ... */ });
it('should throw on invalid input', async () => { /* ... */ });
});
});
Mocking ChromaDB
jest.mock('chromadb', () => ({
ChromaClient: jest.fn().mockImplementation(() => ({
getOrCreateCollection: jest.fn().mockResolvedValue({
query: jest.fn().mockResolvedValue({
documents: [['Sample drug interaction text']],
metadatas: [[{ drug_name: 'aspirin', section_type: 'drug_interactions', source_url: 'https://dailymed.nlm.nih.gov/...' }]],
distances: [[0.15]],
}),
add: jest.fn().mockResolvedValue(undefined),
}),
})),
}));
Supertest Route Test Template
import request from 'supertest';
import app from '../../src/index';
describe('POST /api/interactions/check', () => {
beforeEach(() => jest.clearAllMocks());
it('should return interaction results for valid medications', async () => {
const res = await request(app)
.post('/api/interactions/check')
.send({ medications: ['aspirin', 'warfarin'] });
expect(res.status).toBe(200);
expect(res.body.success).toBe(true);
expect(res.body.data).toHaveProperty('confidence');
expect(res.body.data).toHaveProperty('citations');
});
it('should return 400 when medications array is empty', async () => {
const res = await request(app)
.post('/api/interactions/check')
.send({ medications: [] });
expect(res.status).toBe(400);
expect(res.body.success).toBe(false);
});
});