在一个函数中插入一个特定的 API 请求
Stubbing a specific API request inside a function
如何单独实现父函数内部调用函数的存根?
假设我有这些函数(req1、req2...),它们是来自外部服务的 HTTP 请求,它们都返回不同的值,有没有办法可以单独为 req1 或 req2 应用存根来模拟它们的值?
这样做的目的是因为我需要这样做来测试依赖于 OTP 验证的功能,并且我想绕过所述验证以覆盖我测试中的所有分支。
import request from 'request-promise'
const request1 = async (data) => return request({uri: "service1.com/get", method: "GET"})
const apiRequests = async (data) => {
const req1 = await request1(data); // I want to mock this value to false
const req2 = await request2(data); // I want to mock this value to true
if (req1 && req2) {
const req3 = await request3(data);
const req4 = await request4(data);
return "Second return"
}
return "First return"
}
每当我试图理解更深层次的模拟时,我总是不知所措,而且我在网上看到的大多数例子都没有像我面临的问题那样嵌套,所以我对如何去做有点困惑关于这个。
我也在一个非常严格的设置中工作,所以我真的不允许在 Loopback's built-in testing libraries 之外使用任何其他 libraries/packages。
您可以使用 stub.onCall(n) API.
Defines the behavior of the stub on the nth call. Useful for testing sequential interactions.
此外,sinon 不支持从包导入独立函数,您需要使用 link seams, so that we use proxyquire 包来构造接缝。
例如
apiRequest.ts
:
import request from 'request-promise';
const request1 = async (data) => request({ uri: 'service1.com/get', method: 'GET' });
export const apiRequests = async (data) => {
const req1 = await request1(data);
const req2 = await request1(data);
console.log(req1, req2);
if (req1 && req2) {
const req3 = await request1(data);
const req4 = await request1(data);
return 'Second return';
}
return 'First return';
};
apiRequest.test.ts
import proxyquire from 'proxyquire';
import sinon from 'sinon';
describe('70241641', () => {
it('should second return', async () => {
const rpStub = sinon.stub().onCall(0).resolves(true).onCall(1).resolves(true);
const { apiRequests } = proxyquire('./apiRequest', {
'request-promise': rpStub,
});
const actual = await apiRequests('test data');
sinon.assert.match(actual, 'Second return');
});
it('should first second', async () => {
const rpStub = sinon.stub().onCall(0).resolves(false).onCall(1).resolves(true);
const { apiRequests } = proxyquire('./apiRequest', {
'request-promise': rpStub,
});
const actual = await apiRequests('test data');
sinon.assert.match(actual, 'First return');
});
});
测试结果:
70241641
true true
✓ should second return (2374ms)
false true
✓ should first second
2 passing (2s)
---------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
---------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
apiRequest.ts | 100 | 100 | 100 | 100 |
---------------|---------|----------|---------|---------|-------------------
如何单独实现父函数内部调用函数的存根?
假设我有这些函数(req1、req2...),它们是来自外部服务的 HTTP 请求,它们都返回不同的值,有没有办法可以单独为 req1 或 req2 应用存根来模拟它们的值?
这样做的目的是因为我需要这样做来测试依赖于 OTP 验证的功能,并且我想绕过所述验证以覆盖我测试中的所有分支。
import request from 'request-promise'
const request1 = async (data) => return request({uri: "service1.com/get", method: "GET"})
const apiRequests = async (data) => {
const req1 = await request1(data); // I want to mock this value to false
const req2 = await request2(data); // I want to mock this value to true
if (req1 && req2) {
const req3 = await request3(data);
const req4 = await request4(data);
return "Second return"
}
return "First return"
}
每当我试图理解更深层次的模拟时,我总是不知所措,而且我在网上看到的大多数例子都没有像我面临的问题那样嵌套,所以我对如何去做有点困惑关于这个。
我也在一个非常严格的设置中工作,所以我真的不允许在 Loopback's built-in testing libraries 之外使用任何其他 libraries/packages。
您可以使用 stub.onCall(n) API.
Defines the behavior of the stub on the nth call. Useful for testing sequential interactions.
此外,sinon 不支持从包导入独立函数,您需要使用 link seams, so that we use proxyquire 包来构造接缝。
例如
apiRequest.ts
:
import request from 'request-promise';
const request1 = async (data) => request({ uri: 'service1.com/get', method: 'GET' });
export const apiRequests = async (data) => {
const req1 = await request1(data);
const req2 = await request1(data);
console.log(req1, req2);
if (req1 && req2) {
const req3 = await request1(data);
const req4 = await request1(data);
return 'Second return';
}
return 'First return';
};
apiRequest.test.ts
import proxyquire from 'proxyquire';
import sinon from 'sinon';
describe('70241641', () => {
it('should second return', async () => {
const rpStub = sinon.stub().onCall(0).resolves(true).onCall(1).resolves(true);
const { apiRequests } = proxyquire('./apiRequest', {
'request-promise': rpStub,
});
const actual = await apiRequests('test data');
sinon.assert.match(actual, 'Second return');
});
it('should first second', async () => {
const rpStub = sinon.stub().onCall(0).resolves(false).onCall(1).resolves(true);
const { apiRequests } = proxyquire('./apiRequest', {
'request-promise': rpStub,
});
const actual = await apiRequests('test data');
sinon.assert.match(actual, 'First return');
});
});
测试结果:
70241641
true true
✓ should second return (2374ms)
false true
✓ should first second
2 passing (2s)
---------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
---------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
apiRequest.ts | 100 | 100 | 100 | 100 |
---------------|---------|----------|---------|---------|-------------------