【问题标题】:nock multiple requests mocksnock 多个请求模拟
【发布时间】:2021-03-27 15:51:15
【问题描述】:

我正在更改我的 express 后端并设置端点,该后端通常会向供应商的 API 发出 1 个 http 请求,以便在他们的系统中为之前创建的帐户创建一个支付对象。

之前创建的帐户当前是通过向/partner/v3/account 的供应商 API 发送 POST 请求来创建的。然后,我将他们的响应以及其他详细信息保存到我们的数据库中,以便我们稍后检索。

由于规范的一些变化,每当请求支付对象时,我们都必须重新创建帐户。付款请求在数据库中查找先前创建的帐户,并用于使用帐户 ID 向供应商发出付款请求。但是,由于规范更改,在我们发出付款请求之前,我们必须使用之前创建的帐户详细信息重新创建帐户,并向/partner/v3/account 发送新的 POST 请求。只有在重新创建帐户后,我们才能继续付款请求。

在我最初的 jest 测试中,我有类似以下的内容,并且效果很好:

   describe("POST /v1/accounts/:accountId/payment", () => {
       beforeAll(async () => {
            // nock vendor response for initial creation of account
            nock(VENDOR_URL)
           .post("/partner/v3/account")
           .reply(HttpStatus.CREATED, createRes1);
           
           // post to internal endpoint to create the initial account
           // this saves response and other details to db for retrieval
           await request(app)
          .post("/v1/accounts")
          .send(createReq);
       }

       it("should return successful payment object for user account", async() => {
           nock(VENDOR_URL)
           .post("/payments/setup", paymentReq)
           .reply(HttpStatus.CREATED, paymentRes);

           // this endpoint retrieves the previously created account
           // uses account id to make payment request
           const response = await request(app)
          .post(`/v1/accounts/${accountId}/payment`)
          .send({
              "paymentFreq": "Monthly"
          });

          expect(response.status).toEqual(HttpStatus.OK);
       }
   }

但是,由于需要重新创建帐户,我不得不更改代码以向供应商的 API 发出另一个 http 请求以重新创建帐户。在上面的代码中,我在BeforeAll 中的nock 似乎按预期被调用了一次,但是测试失败了,可能是因为第二个供应商API 请求没有被正确模拟。

如何处理模拟在代码中不同时间调用的相同供应商端点。看来:

  1. BeforeAll 中模拟一次,在 it 块中模拟一次无效
  2. BeforeAll 中嘲笑它两次不起作用,使用times(2)
  3. it 块中模拟两次不起作用

注意:当我说它不起作用时,我的意思是当对/v1/accounts/${accountId}/payment 的 POST 请求时,我希望按照BeforeAll 命令检索以前创建的帐户。但是,如果我在 it 测试中模拟来自 /partner/v3/account 的响应,而不是检索由 BeforeAll 创建的帐户,我会从 it 语句中获取模拟帐户。

it("should return successful payment object for user account", async() => {
// mock response of re-creating account
            nock(VENDOR_URL)
           .post("/partner/v3/account")
           .reply(HttpStatus.CREATED, createRes2);

// mock response of making account payment
           nock(VENDOR_URL)
           .post("/payments/setup", paymentReq)
           .reply(HttpStatus.CREATED, paymentRes);

           // this endpoint retrieves the previously created account
           // uses previous account details to re-created account
           // uses new account id to make payment request
           const response = await request(app)
          .post(`/v1/accounts/${accountId}/payment`)
          .send({
              "paymentFreq": "Monthly"
          });

          expect(response.status).toEqual(HttpStatus.OK);
       }

注意:我需要nock /partner/v3/account 端点调用,以便每个调用返回不同的东西,因为重点是测试帐户的重新创建,因此帐户 ID 将与供应商的反应不同。我的模拟响应具有不同的帐户 ID,因此这应该是正确的,但如前所述,第一次在 /v1/accounts/${accountId}/payment 中检索帐户时,它会获得第二个模拟响应,而不是来自BeforeAll 的第一个模拟响应。

【问题讨论】:

  • 你能解释一下当你把它添加到it的顶部时会发生什么:nock(VENDOR_URL).post("/partner/v3/account").reply(HttpStatus.CREATED, otherCreateRes)。请注意正在使用的otherCreateRes,以便您可以返回第二个 ID 等。
  • @MattR.Wilson 感谢您澄清问题,我添加了更多详细信息来阐明为什么模拟从 POSTing 到 /partner/v3/account 的多个响应是一个问题。也许我需要按特定顺序放置这些模拟或清除或重置nock

标签: javascript jestjs nock


【解决方案1】:

不是我想要的解决方案,但使用 times 似乎至少模拟了对供应商 API 的响应 N 次,在这种情况下是两次。

这不是最好的解决方案,因为在向供应商 API 创建帐户的第一个请求中,会创建一个帐户 ID,这在下一个请求中应该有所不同,但至少它让我更接近我的需要。

我在it 声明中得到了以下结果:

nock(HISCOX_URL)
    response payload
    .post("/partner/v3/account/")
    .times(2)
    .reply(HttpStatus.CREATED, createRes2)

我试图以链式方式模拟从 POST 到此端点的响应,但它不起作用:

nock(HISCOX_URL)
    .post("/partner/v3/account/")
    .reply(HttpStatus.CREATED, createRes2) // account id X
    .post("/partner/v3/account/")
    .reply(HttpStatus.CREATED, reCreateRes2); // account id Y

【讨论】:

  • 我也有同样的问题,但提供的解决方案不起作用。你在哪里可以通过其他方式解决这个问题?
  • 有趣!我和你们两个在这里有同样的问题,比如: 1. 请求 1 发布类似 foo 的正文,回复类似 fooResponse 2. 请求 2 发布类似 bar 的正文并回复类似 barResponse 但是,我不知道如何让 nock 区分两者并做出相应的反应。我尝试在一个循环中添加侦听器,但它似乎最终成为第一个循环,成为“模拟”......
猜你喜欢
  • 2016-06-09
  • 1970-01-01
  • 2020-09-02
  • 2017-04-15
  • 2018-05-09
  • 2016-05-29
  • 2015-10-11
  • 2019-05-06
  • 1970-01-01
相关资源
最近更新 更多