Nock 拦截器

基础拦截器

const nock = require('nock'); const axios = require('axios'); nock('https://api.example.com') .get('/users') .reply(200, [{ id: 1, name: '张三' }]); const { data } = await axios.get('https://api.example.com/users'); // 带查询字符串 nock('https://api.example.com') .get('/search') .query({ q: '测试', page: '1' }) .reply(200, { results: [] }); // POST 匹配请求体 nock('https://api.example.com') .post('/users', { name: '李四', email: 'lisi@example.com' }) .reply(201, { id: 2, name: '李四' });

响应体与状态码

// 自定义响应头 nock('https://api.example.com') .get('/users') .reply(200, [{ id: 1 }], { 'X-Total-Count': '42', 'Content-Type': 'application/json', }); // 错误响应 nock('https://api.example.com') .get('/protected') .reply(401, { error: '未授权' }); // 模拟网络错误 nock('https://api.example.com') .get('/broken') .replyWithError('ECONNRESET'); // 延迟响应 nock('https://api.example.com') .get('/slow') .delay(500) .reply(200, { data: '慢响应' });

Scope 链式调用与持久化

nock('https://api.example.com') .get('/users').reply(200, [{ id: 1 }]) .post('/users').reply(201, { id: 2 }) .delete('/users/1').reply(204); // 持久化(所有测试都可用) nock('https://api.example.com') .get('/config') .reply(200, { env: 'test' }) .persist(); // 响应 N 次后停止 nock('https://api.example.com') .get('/items') .times(3) .reply(200, []);

请求匹配 — 请求体与请求头

// 自定义匹配函数 nock('https://api.example.com') .post('/users', body => { return body.role === 'admin'; }) .reply(201, { id: 1, role: 'admin' }); // 匹配请求头 nock('https://api.example.com', { reqheaders: { 'authorization': 'Bearer mytoken', 'content-type': /application\/json/, }, }) .get('/secure') .reply(200, { secret: '数据' });

清理与验证

afterEach(() => { nock.cleanAll(); }); test('所有 mock 均被调用', async () => { const scope = nock('https://api.example.com') .get('/users').reply(200, []) .get('/config').reply(200, {}); await Promise.all([ axios.get('https://api.example.com/users'), axios.get('https://api.example.com/config'), ]); expect(scope.isDone()).toBe(true); expect(nock.pendingMocks()).toHaveLength(0); }); // 允许真实网络请求 nock.enableNetConnect('localhost'); nock.disableNetConnect();

nock.back — 录制与回放

nock.back.fixtures = path.join(__dirname, 'fixtures'); nock.back.setMode('record'); test('录制真实 API 响应', async () => { const { nockDone } = await nock.back('github-users.json'); const response = await fetch('https://api.github.com/users/octocat'); const data = await response.json(); nockDone(); expect(data.login).toBe('octocat'); }); // 模式说明: // record — 无 fixture 时录制,有则回放 // playback — 仅使用 fixture(缺失则失败) // wild — 禁用拦截(所有请求真实发出)