如何检查多次调用开玩笑间谍的多个参数?
How to check multiple arguments on multiple calls for jest spies?
我在 React 组件中有以下功能:
onUploadStart(file, xhr, formData) {
formData.append('filename', file.name);
formData.append('mimeType', file.type);
}
这是我的测试,至少可以调用间谍:
const formData = { append: jest.fn() };
const file = { name: 'someFileName', type: 'someMimeType' };
eventHandlers.onUploadStart(file, null, formData);
expect(formData.append).toHaveBeenCalledWith(
['mimeType', 'someMimeType'],
['fileName', 'someFileName']
);
但是,断言无效:
Expected mock function to have been called with:
[["mimeType", "someMimeType"], ["fileName", "someFileName"]]
But it was called with:
["mimeType", "someMimeType"], ["filename", "someFileName"]
正确的使用方法是什么toHaveBeenCalledWith
?
签名是 .toHaveBeenCalledWith(arg1, arg2, ...)
,其中 arg1, arg2, ...
表示在 单个 调用中 (see)。
如果您想测试多个调用,只需 expect
多次。
遗憾的是,我还没有找到测试多次调用顺序的方法。
我能够模拟多个调用并以这种方式检查参数:
expect(mockFn.mock.calls).toEqual([
[arg1, arg2, ...], // First call
[arg1, arg2, ...] // Second call
]);
其中 mockFn
是您模拟的函数名称。
这对我也有用...初始页面加载进行默认搜索...用户交互和点击搜索进行另一次搜索...需要验证搜索过程是否正确增加了搜索值...
let model = {
addressLine1: null,
addressLine2: null,
city: null,
country: "US"};
let caModel = { ...model, country: "CA" };
const searchSpy = props.patientActions.searchPatient;
expect(searchSpy.mock.calls).toEqual([[{ ...model }], [{ ...caModel }]]);
自 jest 23.0 以来有 .toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)
https://jestjs.io/docs/expect#tohavebeennthcalledwithnthcall-arg1-arg2-
Also under the alias: .nthCalledWith(nthCall, arg1, arg2, ...)
If you have a mock function, you can use .toHaveBeenNthCalledWith
to test what arguments it was nth called with. For example, let's say you have a drinkEach(drink, Array<flavor>)
function that applies f
to a bunch of flavors, and you want to ensure that when you call it, the first flavor it operates on is 'lemon'
and the second one is 'octopus'
. You can write:
test('drinkEach drinks each drink', () => {
const drink = jest.fn();
drinkEach(drink, ['lemon', 'octopus']);
expect(drink).toHaveBeenNthCalledWith(1, 'lemon');
expect(drink).toHaveBeenNthCalledWith(2, 'octopus');
});
Note: the nth argument must be positive integer starting from 1.
您还可以测试 toHaveBeenCalledWith
并针对每个预期参数组合测试多次。
一个示例是 Google Analytics plugin api 使用具有不同参数组合的相同函数调用。
function requireGoogleAnalyticsPlugins() {
...
ga('create', 'UA-XXXXX-Y', 'auto');
ga('require', 'localHitSender', {path: '/log', debug: true});
ga('send', 'pageview');
}
为了对此进行测试,下面的示例测试了 GA 已使用各种参数组合被调用了三次。
describe("requireGoogleAnalyticsPlugins", () => {
it("requires plugins", () => {
requireGoogleAnalyticsPlugins();
expect(GoogleAnalytics.ga.toHaveBeenCalledTimes(3);
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('create', 'UA-XXXXX-Y', 'auto');
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('require', 'localHitSender', {path: '/log', debug: true});
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('send', 'pageview');
});
});
在 OP 案例中,您可以使用
进行测试
expect(formData.append).toHaveBeenCalledWith('mimeType', 'someMimeType');
expect(formData.append).toHaveBeenCalledWith('fileName', 'someFileName');
基于 Andi 的另一种解决方案。 Select 您想要的调用并检查参数的值。在此示例中,选择了第一个调用:
expect(mockFn.mock.calls[0][0]).toEqual('first argument');
expect(mockFn.mock.calls[0][1]).toEqual('second argument');
我建议查看这个 Jest 备忘单:
您还可以为每次调用创建一个预期参数数组并对其进行循环:
const expectedArgs = ['a', 'b', 'c', 'd']
expectedArgs.forEach((arg, index) =>
expect(myFunc).toHaveBeenNthCalledWith(index + 1, arg))
这个解决方案考虑了调用的顺序。如果您不关心顺序,可以使用不带索引的 toHaveBeenCalledWith
。
要重置模拟的计数,您可以调用 jest.clearAllMocks
。
这在 beforeEach
测试之间最有用。
beforeEach(() => jest.clearAllMocks());
您可以在您的间谍上使用 .calls
returns 一个 Calls
接口,其中包括以下方法:
/** will return the arguments passed to call number index **/
argsFor(index: number): any[];
那么您可以执行以下操作:
const formData = { append: jest.fn() };
const file = { name: 'someFileName', type: 'someMimeType' };
eventHandlers.onUploadStart(file, null, formData);
expect(formData.append).toHaveBeenCalledTimes(2);
expect(formData.append.argsFor(0)).toEqual(
['fileName', 'someFileName']
);
expect(formData.append.argsFor(1)).toEqual(
['mimeType', 'someMimeType'],
);
我在 React 组件中有以下功能:
onUploadStart(file, xhr, formData) {
formData.append('filename', file.name);
formData.append('mimeType', file.type);
}
这是我的测试,至少可以调用间谍:
const formData = { append: jest.fn() };
const file = { name: 'someFileName', type: 'someMimeType' };
eventHandlers.onUploadStart(file, null, formData);
expect(formData.append).toHaveBeenCalledWith(
['mimeType', 'someMimeType'],
['fileName', 'someFileName']
);
但是,断言无效:
Expected mock function to have been called with:
[["mimeType", "someMimeType"], ["fileName", "someFileName"]]
But it was called with:
["mimeType", "someMimeType"], ["filename", "someFileName"]
正确的使用方法是什么toHaveBeenCalledWith
?
签名是 .toHaveBeenCalledWith(arg1, arg2, ...)
,其中 arg1, arg2, ...
表示在 单个 调用中 (see)。
如果您想测试多个调用,只需 expect
多次。
遗憾的是,我还没有找到测试多次调用顺序的方法。
我能够模拟多个调用并以这种方式检查参数:
expect(mockFn.mock.calls).toEqual([
[arg1, arg2, ...], // First call
[arg1, arg2, ...] // Second call
]);
其中 mockFn
是您模拟的函数名称。
这对我也有用...初始页面加载进行默认搜索...用户交互和点击搜索进行另一次搜索...需要验证搜索过程是否正确增加了搜索值...
let model = {
addressLine1: null,
addressLine2: null,
city: null,
country: "US"};
let caModel = { ...model, country: "CA" };
const searchSpy = props.patientActions.searchPatient;
expect(searchSpy.mock.calls).toEqual([[{ ...model }], [{ ...caModel }]]);
自 jest 23.0 以来有 .toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)
https://jestjs.io/docs/expect#tohavebeennthcalledwithnthcall-arg1-arg2-
Also under the alias: .nthCalledWith(nthCall, arg1, arg2, ...)
If you have a mock function, you can use
.toHaveBeenNthCalledWith
to test what arguments it was nth called with. For example, let's say you have adrinkEach(drink, Array<flavor>)
function that appliesf
to a bunch of flavors, and you want to ensure that when you call it, the first flavor it operates on is'lemon'
and the second one is'octopus'
. You can write:
test('drinkEach drinks each drink', () => {
const drink = jest.fn();
drinkEach(drink, ['lemon', 'octopus']);
expect(drink).toHaveBeenNthCalledWith(1, 'lemon');
expect(drink).toHaveBeenNthCalledWith(2, 'octopus');
});
Note: the nth argument must be positive integer starting from 1.
您还可以测试 toHaveBeenCalledWith
并针对每个预期参数组合测试多次。
一个示例是 Google Analytics plugin api 使用具有不同参数组合的相同函数调用。
function requireGoogleAnalyticsPlugins() {
...
ga('create', 'UA-XXXXX-Y', 'auto');
ga('require', 'localHitSender', {path: '/log', debug: true});
ga('send', 'pageview');
}
为了对此进行测试,下面的示例测试了 GA 已使用各种参数组合被调用了三次。
describe("requireGoogleAnalyticsPlugins", () => {
it("requires plugins", () => {
requireGoogleAnalyticsPlugins();
expect(GoogleAnalytics.ga.toHaveBeenCalledTimes(3);
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('create', 'UA-XXXXX-Y', 'auto');
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('require', 'localHitSender', {path: '/log', debug: true});
expect(GoogleAnalytics.ga).toHaveBeenCalledWith('send', 'pageview');
});
});
在 OP 案例中,您可以使用
进行测试expect(formData.append).toHaveBeenCalledWith('mimeType', 'someMimeType');
expect(formData.append).toHaveBeenCalledWith('fileName', 'someFileName');
基于 Andi 的另一种解决方案。 Select 您想要的调用并检查参数的值。在此示例中,选择了第一个调用:
expect(mockFn.mock.calls[0][0]).toEqual('first argument');
expect(mockFn.mock.calls[0][1]).toEqual('second argument');
我建议查看这个 Jest 备忘单:
您还可以为每次调用创建一个预期参数数组并对其进行循环:
const expectedArgs = ['a', 'b', 'c', 'd']
expectedArgs.forEach((arg, index) =>
expect(myFunc).toHaveBeenNthCalledWith(index + 1, arg))
这个解决方案考虑了调用的顺序。如果您不关心顺序,可以使用不带索引的 toHaveBeenCalledWith
。
要重置模拟的计数,您可以调用 jest.clearAllMocks
。
这在 beforeEach
测试之间最有用。
beforeEach(() => jest.clearAllMocks());
您可以在您的间谍上使用 .calls
returns 一个 Calls
接口,其中包括以下方法:
/** will return the arguments passed to call number index **/
argsFor(index: number): any[];
那么您可以执行以下操作:
const formData = { append: jest.fn() };
const file = { name: 'someFileName', type: 'someMimeType' };
eventHandlers.onUploadStart(file, null, formData);
expect(formData.append).toHaveBeenCalledTimes(2);
expect(formData.append.argsFor(0)).toEqual(
['fileName', 'someFileName']
);
expect(formData.append.argsFor(1)).toEqual(
['mimeType', 'someMimeType'],
);