【发布时间】: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 请求没有被正确模拟。
如何处理模拟在代码中不同时间调用的相同供应商端点。看来:
- 在
BeforeAll中模拟一次,在it块中模拟一次无效 - 在
BeforeAll中嘲笑它两次不起作用,使用times(2) - 在
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