测试回购已创建:https://github.com/leongaban/pact-io-js-test
预期
运行npm run pactTest
,这将为我的TotalPayout.test.pact.ts
文件创建一个Pact文件。
结果
D, [#38238] DEBUG -- : {
"description": "a GET request with a user id",
"request": {
"method": "GET",
"path": "/frontoffice/api/liquidity-pool/get-total-payout",
"headers": {
"Accept": "application/json"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
}
}
}
W, [#38238] WARN -- : Verifying - actual interactions do not match expected interactions.
Missing requests:
GET /frontoffice/api/liquidity-pool/get-total-payout
W, [#38238] WARN -- : Missing requests:
GET /frontoffice/api/liquidity-pool/get-total-payout
这是我的契约文件
// @ts-ignore
import path from 'path';
// @ts-ignore
import { Pact } from '@pact-foundation/pact';
import { getTotalPayout } from './LiquidityPool';
// const port = 12345;
const endpoint = '/frontoffice/api/liquidity-pool/get-total-payout';
const EXPECTED_BODY = {
total_payout: 100.21,
};
const userId = 'foo';
describe('The API', () => {
// Copy this block once per interaction under test
describe('getUsersTotalPayout', () => {
beforeEach(() => {
const interaction = {
uponReceiving: 'a GET request with a user id',
withRequest: {
method: 'GET',
path: endpoint,
headers: {
Accept: 'application/json',
},
},
willRespondWith: {
status: 200,
headers: {
'Content-Type': 'application/json'
},
data: EXPECTED_BODY
},
};
// @ts-ignore
return provider.addInteraction(interaction);
});
// add expectations
it('Should call getUsersTotalPayout and return an object with the total_payout', done => {
getTotalPayout(userId)
.then((response: any) => {
console.log('response', response);
console.log('EXPECTED_BODY', EXPECTED_BODY);
expect(response).toEqual(EXPECTED_BODY);
})
.then(done);
});
});
});
这是包含
getTotalPayout
函数的服务文件:该端点尚不存在,但是据我了解,该Pact测试应该仍然有效。
// @TODO Note, this is the placeholder for LiquidityPool API endpoints
// @ts-ignore
import axios, * as others from 'axios';
const endpoint = '/frontoffice/api/liquidity-pool/';
export const getTotalPayout = async (userId: string) => {
const response = await axios.get(`${endpoint}get-total-payout`, { params: userId });
return response.data;
};
也是我在
axios
中的src/__mocks__/axios.ts
模拟// tslint:disable-next-line:no-empty
const mockNoop = () => new Promise(() => {});
export default {
get: jest.fn(() => Promise.resolve({ data: { total_payout: 100.21 }})),
default: mockNoop,
post: mockNoop,
put: mockNoop,
delete: mockNoop,
patch: mockNoop
};
最佳答案
非常简单-您的测试未在Pact Mock服务器上达到路径/frontoffice/api/liquidity-pool/get-total-payout
。
您已将Pact设置为在http://localhost:1234
上运行,因此需要将实际代码配置为击中该服务器,而不是实际服务器。
在axios配置中,您正在模拟http请求库,因此它什么也不做。因此,当您的实际代码使用它时,它不会发出http调用,并且Pact测试也会失败,因为它期望以某种形状调用并且没有得到它。
这是您需要更改的内容:
似乎已使用Axios,但您的package.json中没有使用Axios。我猜是因为您在嘲笑(2)。您需要一个实际的http请求库,因此您可能应该只安装axios
模拟Axios可以提供固定答复,请勿在Pact测试期间模拟Axios(如果需要,对于本地开发人员也可以),因为这将阻止对Pact进行真正的调用。 Pact需要真正的http调用,以便它可以检查您的代码在做正确的事情,然后将找到的内容写到“合同”中
在测试中配置axios以打通Pact模拟服务。假设您使用axios,则应执行以下操作:
pactSetup.ts:
// Configure axios to use the Pact mock server for Pact tests
import axios from "axios";
axios.defaults.baseURL = "http://localhost:1234";
阅读Pact吐出的日志文件。它告诉您发生了什么。再重申一次:您已告知Pact,
/frontoffice/api/liquidity-pool/get-total-payout
上应该有一个互动,但从未收到。使您的实际代码达到此目标,然后就可以了。最后,顺便说一句,一旦开始生成Pact(固定1-4之后),您可能希望将Pact用作本地开发的本地存根服务器。该二进制文件实际上已经安装在您的node_modules中,其运行方式的文档位于https://github.com/pact-foundation/pact-ruby-standalone/releases
我通常在package.json中有一个脚本,如下所示:
"stubs": "$(find . -name pact-stub-service | head -n 1) pacts/* --port 4000"
然后,您可以运行
npm run stubs
并在端口4000上运行提供程序的本地存根,并将所有请求/响应放入测试中。关于javascript - PACT.io:运行npm时,运行pactTest会遇到缺少请求的错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52520827/