在NodeJS中使用Jest对类进行部分模拟

g2ieeal7  于 2023-11-15  发布在  Jest
关注(0)|答案(1)|浏览(121)

我有一个函数extractPayloadDates,它接受对话流Agent的一个示例,并从中获取和解析数据。我想只模拟Agent的一个方法getParameter,因为在测试的函数中没有更多的方法使用。我在网上找到了这个代码,但它不工作

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个其他属性。ts(2740)index.d.ts(124,53):预期类型来自此签名的返回类型。
我也尝试使用jest.spyOn,但问题是,我不能创建代理示例,因为它需要许多其他对象。

编辑3.9.2019更多代码

Agent.ts

export class Agent {
  private payload: DialogFlowPayload[] = [];

  constructor(readonly webhookClient: WebhookClient, private readonly chatter: Chatter) {}
...
}

WebhookClientChatter在构造函数中也有更多的依赖.
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<any,any>”类型的参数不能分配给“Chatter”类型的参数。“Mock<any,any>”类型中缺少属性“getMessage”,但“Chatter”类型中需要该属性
我真的必须创建WebhookClient及其所有依赖项,并对Chatter做同样的事情吗?如果我这样做,我必须创建多个类的示例,只是为了模拟Agent中的一个方法,然后不会使用任何依赖项。

zbdgwd5y

zbdgwd5y1#

从笑话的文件
如果想覆盖原来的函数,可以使用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 };


单元测试,只模拟agentgetParameter方法,保持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

相关问题