// Mock the MongoDB module completely const mockDb = { collection: jest.fn().mockReturnValue({ findOne: jest.fn(), insertOne: jest.fn(), updateOne: jest.fn(), deleteOne: jest.fn() }), admin: jest.fn().mockReturnValue({ ping: jest.fn().mockResolvedValue(true) }) } const mockClient = { connect: jest.fn(), close: jest.fn().mockResolvedValue(undefined), db: jest.fn().mockReturnValue(mockDb) } // The connect method should resolve to the client itself mockClient.connect.mockResolvedValue(mockClient) const MockedMongoClient = jest.fn().mockImplementation(() => mockClient) // Mock the mongodb module jest.mock('mongodb', () => ({ MongoClient: MockedMongoClient })) // Restore environment before tests const originalEnv = process.env describe('MongoDB Connection (Unit Tests)', () => { beforeEach(() => { jest.resetModules() process.env = { ...originalEnv, MONGODB_URI: 'mongodb://localhost:27017/test', MONGODB_DB: 'test' } jest.clearAllMocks() // Reset the mock implementation MockedMongoClient.mockImplementation(() => mockClient as any) mockClient.db.mockReturnValue(mockDb) }) afterEach(() => { process.env = originalEnv }) describe('MongoDB URI validation', () => { it('should throw error when MONGODB_URI is not set', () => { // This test is tricky because the module is cached // We'll test this by clearing the module cache and mocking process.env const originalMongodbUri = process.env.MONGODB_URI delete process.env.MONGODB_URI // Clear module cache to force re-import jest.resetModules() const { getClientPromise } = require('./mongodb') expect(() => getClientPromise()).toThrow('Please add MONGODB_URI to your environment variables') // Restore environment process.env.MONGODB_URI = originalMongodbUri }) }) describe('Database connection', () => { it('should create MongoClient with correct URI and options', async () => { // Import after setting up the mock const { getClientPromise } = await import('./mongodb') await getClientPromise() expect(MockedMongoClient).toHaveBeenCalledWith( process.env.MONGODB_URI, expect.objectContaining({ maxPoolSize: 10, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000 }) ) }) it('should return database instance', async () => { const { getDb } = await import('./mongodb') const result = await getDb() expect(result).toBe(mockDb) expect(typeof result.collection).toBe('function') }) it('should return collection from database', async () => { const { getCollection } = await import('./mongodb') const collection = await getCollection('test_collection') expect(collection).toBeDefined() expect(mockDb.collection).toHaveBeenCalledWith('test_collection') expect(typeof collection.findOne).toBe('function') }) it('should check MongoDB connection successfully', async () => { const { checkMongoConnection } = await import('./mongodb') const result = await checkMongoConnection() expect(result).toBe(true) }) it('should return false on MongoDB connection failure', async () => { // Create a failing client const failingClient = { connect: jest.fn().mockRejectedValue(new Error('Connection failed')), db: jest.fn().mockRejectedValue(new Error('Connection failed')), close: jest.fn() } MockedMongoClient.mockImplementation(() => failingClient as any) // Clear the module cache and re-import jest.resetModules() const { checkMongoConnection } = await import('./mongodb') const result = await checkMongoConnection() expect(result).toBe(false) }) }) describe('Connection reuse and caching', () => { it('should reuse the same MongoClient instance for multiple calls', async () => { const { getClientPromise } = await import('./mongodb') const client1 = await getClientPromise() const client2 = await getClientPromise() // Should be the same client instance expect(client1).toBe(client2) }) }) })