Define a consumer contract for a user API and verify it against a mock provider.
1 import { Pact } from '@pact-foundation/pact'; 2 import { like, term } from '@pact-foundation/pact/src/dsl/matchers'; 3 import path from 'path'; 4 5 const provider = new Pact({ 6 consumer: 'frontend-web', 7 provider: 'user-api', 8 port: 1234, 9 log: path.resolve(process.cwd(), 'logs', 'pact.log'), 10 dir: path.resolve(process.cwd(), 'pacts'), 11 logLevel: 'info', 12 }); 13 14 // Simple client 15 class UserApiClient { 16 constructor(private baseUrl: string) {} 17 async getUser(id: string) { 18 const res = await fetch(`${this.baseUrl}/users/${id}`); 19 if (!res.ok) throw new Error(`HTTP ${res.status}`); 20 return res.json(); 21 } 22 } 23 24 describe('UserApiClient — Pact Contract', () => { 25 beforeAll(() => provider.setup()); 26 afterAll(() => provider.finalize()); 27 afterEach(() => provider.verify()); 28 29 it('gets user by ID', async () => { 30 await provider.addInteraction({ 31 state: 'user 42 exists', 32 uponReceiving: 'a GET request for user 42', 33 withRequest: { 34 method: 'GET', 35 path: '/users/42', 36 }, 37 willRespondWith: { 38 status: 200, 39 headers: { 'Content-Type': 'application/json' }, 40 body: { 41 id: like('42'), 42 name: like('Alice'), 43 email: term({ generate: 'alice@example.com', matcher: '.+@.+\..+' }), 44 }, 45 }, 46 }); 47 48 const client = new UserApiClient('http://localhost:1234'); 49 const user = await client.getUser('42'); 50 51 expect(user.id).toBeDefined(); 52 expect(user.name).toBeDefined(); 53 expect(user.email).toMatch(/.+@.+/); 54 }); 55 });
Pact file generated; consumer client works against mock; pact ready for provider
Sign in to share your feedback and join the discussion.