如果没有请求正文,如何使用 nock 发送多个响应

How to send multiple response using nock if there is no request body

我正在调用流 api http://dummy-streaming-api/customer-details,它接受 post 请求并发送一些数据。它不需要任何请求主体。 我想在单元测试的 Node.js 应用程序中使用 nock 模拟响应。 我已经有一个快乐旅程的测试用例,其中 nock 拦截请求并发送 200 和一些数据。

nock('http://dummy-streaming-api')
    .persist()
    .get('/customer-details')
    .reply(200,dummyResponse)

我如何编写发送 500 或 404 的 nock,因为我没有请求主体来区分 2 个请求。

TLDR;

我建议删除 .persist() 并在每个测试中设置 nock 以得到您想要的响应。

详情

.persist() 调用使该特定箭尾连续多次调用存在。有很多功能(例如,发送不同的回复,或 scope.isDone())你会因为坚持 nock 而错过,并且坚持会打开一些 hard-to-find 错误。

我建议删除 .persist() 并在每个测试中创建一个新的箭尾,并在您的 afterEach 中创建 运行 nock.cleanAll()。这可以让您更好地了解 nock 的当前状态以及每个测试真正测试的内容。

示例:

afterEach(() => nock.cleanAll())

it('should call the endpoint', async () => {
  const streamApiNock = nock('http://dummy-streaming-api')
    .get('/customer-details')
    .reply(200, dummyResponse)

  const response = await myCallToApi(url)
  expect(response.statusCode).to.equal(200)
  expect(streamApiNock.isDone()).to.be.true()
}

it('should handle an error from the endpoint', async () => {
  const streamApiNock = nock('http://dummy-streaming-api')
    .get('/customer-details')
    .reply(500, {err: 'my error'})

  const response = await myCallToApi(url) 
  // this might need a try/catch or an expect().to.reject() or whatever
  // depending on what testing lib you're using

  expect(response.statusCode).to.equal(500)
  expect(streamApiNock.isDone()).to.be.true()
}

如果您有多个测试需要相同的 nock 响应并且不想继续编写代码,我会将它们全部放在 describe('200 response') 块中,将 nock 调用放在 beforeEach(),以及 afterEach() 中的 nock.cleanAll()。这样,测试状态在代码的每个部分都是显而易见的,并以一种可以防止 hard-to-detect 其他开发人员错误的方式进行清理。

如果您需要在 同一个测试 中多次调用,比如您正在测试内部获取函数或其他东西的重试功能,我建议调用 nock 两次(并使用chaining.times() 以获得更清晰的语法)。请参阅文档:Intercepting multiple calls

示例:

afterEach(() => nock.cleanAll())

// Sets up nock twice to check for rate limiting/retry functionality
it('should retry 3 times on 500', async () => {
  nock('http://dummy-streaming-api')
    .get('/customer-details')
    .reply(500, err)
    .get('/customer-details')
    .reply(500, err)
    .get('/customer-details')
    .reply(200, payload)
  
  await myRetryFunction();

  expect(nock.isDone()).to.be.true()
}

it('should retry 3 times on 500', async () => {
  nock('http://dummy-streaming-api')
    .get('/customer-details')
    .times(2)
    .reply(500, err)
    .get('/customer-details')
    .reply(200, payload)
  
  await myRetryFunction();

  expect(nock.isDone()).to.be.true()
}

链接:Chaining

nock.persist() 的文档:Docs