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 — 禁用拦截(所有请求真实发出)