我有一个函数
extractPayloadDates
,它接受对话流Agent
的实例并从中获取和解析数据。我只想模拟 getParameter
的单个方法 Agent
,因为测试函数中没有使用更多方法。我在网上找到了这个代码,但它不起作用
import { Agent } from '../../src/dialogflow/Agent';
import { extractPayloadDates } from '../../src/intents/extractPayloadDates';
describe('extractPayloadDates', () => {
it('tests extracting string', () => {
const AgentMock = jest.fn<Agent, []>(() => ({
getParameter: () => {
return 'some date';
}
}));
const agent = new AgentMock();
expect(extractPayloadDates(agent)).toEqual('some date');
});
});
此代码产生以下错误:
输入 '{ getParameter: () => string; }' 缺少类型“Agent”中的以下属性:payload、webhookClient、chatter、getOriginalRequest 和 13 more.ts(2740) index.d.ts(124, 53):预期类型来自此签名的返回类型。
我也尝试使用
jest.spyOn
,但问题是,我无法创建代理实例,因为它需要许多其他对象。
代理.ts
export class Agent {
private payload: DialogFlowPayload[] = [];
constructor(readonly webhookClient: WebhookClient, private readonly chatter: Chatter) {}
...
}
WebhookClient 和 Chatter 在其构造函数中也有更多依赖项...
extractPayloads.spec.ts
import { Agent } from '../../src/dialogflow/Agent';
import { extractPayloadDates } from '../../src/intents/extractPayloadDates';
describe('extractPayloadDates', () => {
it('tests extracting string', () => {
const webhookMock = jest.fn();
const chatter = jest.fn();
const agent = new Agent(webhookMock, chatter);
expect(extractPayloadDates(agent)).toEqual('some date');
});
});
这会产生另一个错误:
“Mock
”类型的参数不可分配给“Chatter”类型的参数。 “Mock ”类型中缺少属性“getMessage”,但“Chatter”类型中需要属性“getMessage”
我真的还必须创建 WebhookClient 及其所有依赖项并对 Chatter 执行相同的操作吗?如果这样做,我必须创建多个类的实例只是为了模拟 Agent 中的 1 个方法,然后该方法将不会使用任何依赖项。
来自 jest 的文档
如果想覆盖原来的函数,可以使用 jest.spyOn(object, methodName).mockImplementation(() => customImplementation) 或 object[methodName] = jest.fn(() => customImplementation);
jest.spyOn
内部调用jest.fn
。所以你只能像这样模拟 getParameter
代理方法:
extractPayloadDates.ts
:
function extractPayloadDates(agent) {
return agent.getParameter();
}
export { extractPayloadDates };
Agent.ts
:
interface DialogFlowPayload {}
interface WebhookClient {}
interface Chatter {
getMessage(): any;
}
class Agent {
private payload: DialogFlowPayload[] = [];
constructor(readonly webhookClient: WebhookClient, private readonly chatter: Chatter) {}
public getParameter() {
return 'real data';
}
public otherMethod() {
return 'other real data';
}
}
export { Agent, Chatter };
单元测试,仅mock
getParameter
的agent
方法,保留otherMethod
原来的实现
import { extractPayloadDates } from './extractPayloadDates';
import { Agent, Chatter } from './Agent';
const webhookMock = jest.fn();
const chatter: jest.Mocked<Chatter> = {
getMessage: jest.fn()
};
const agent = new Agent(webhookMock, chatter);
describe('extractPayloadDates', () => {
it('should only mock getParameter method of agent', () => {
agent.getParameter = jest.fn().mockReturnValueOnce('mocked data');
const actualValue = extractPayloadDates(agent);
expect(actualValue).toEqual('mocked data');
expect(agent.otherMethod()).toBe('other real data');
});
});
PASS src/stackoverflow/57428542/extractPayloadDates.spec.ts
extractPayloadDates
✓ should only mock getParameter method of agent (7ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.484s, estimated 3s