如何使用 sinon js/loopback testlab 模拟来自 twilio-node 的 messages.create() 方法的返回值?

Posted

技术标签:

【中文标题】如何使用 sinon js/loopback testlab 模拟来自 twilio-node 的 messages.create() 方法的返回值?【英文标题】:How to mock the return value of messages.create() method from twilio-node using sinon js/loopback testlab? 【发布时间】:2021-12-02 20:26:44 【问题描述】:

我正在尝试模拟 twilio-node 库中 messages.create() 方法的返回值。

由于create方法驻留在名为messages的接口中,我不能直接模拟create方法的返回值。

我的单元测试:

import 
  createStubInstance,
  StubbedInstanceWithSinonAccessor,
 from '@loopback/testlab';
import sinon from 'sinon';
import Twilio from '../../../../clients/whatsapp-sms-clients/twilio.whatsapp-sms-clients';
import twilio from 'twilio';

describe('Twilio client (UnitTest)', () => 
  let twilioMock: StubbedInstanceWithSinonAccessor<twilio.Twilio>;
  let logger: StubbedInstanceWithSinonAccessor<LoggingService>;
  let twilioClient: Twilio;

  beforeEach(() => 
    twilioMock = createStubInstance(twilio.Twilio);
    logger = createStubInstance(LoggingService);
    twilioClient = new Twilio(twilioMock, logger);
  );

  it('should create the message', async () => 
    twilioMock.stubs.messages.create.resolves(
      // mocked value
    );
  );
);

提前致谢。

【问题讨论】:

【参考方案1】:

这里是 Twilio 开发者宣传员。

我以前没有像这样使用过testlab/sinon,但我想我知道你需要做什么,如果不是正确的语法。

您需要存根对twilioMock.messages 的响应以返回具有create 属性的对象,该属性是解析为所需结果的存根函数。这样的事情可能会奏效,或者至少让你走上正轨:

  it('should create the message', async () => 
    // Create stub for response to create method:
    const createStub = sinon.stub().resolves(
      // mocked value
    );
    // Stub the value "messages" to return an object that has a create property with the above stub:
    twilioMock.stubs.messages.value( 
      create: createStub
    );

    // Rest of the test script
  );

编辑

好的,使用上面的value 不起作用。我又试了一次。此版本从示例中删除了您的自定义 Twilio 包装器,只是直接在 Twilio 客户端存根本身上调用事物。希望您可以以此为灵感,将其应用于您的测试。

我意识到twilioClient.messages is a getter 是动态定义的。所以,我直接在存根客户端上存根了结果。

import 
  createStubInstance,
  StubbedInstanceWithSinonAccessor,
 from "@loopback/testlab";
import sinon from "sinon";
import  Twilio  from "twilio";

describe("Twilio client (UnitTest)", () => 
  let twilioMock: StubbedInstanceWithSinonAccessor<Twilio>;

  beforeEach(() => 
    twilioMock = createStubInstance(Twilio);
  );

  it("should create the message", async () => 
    const createStub = sinon.stub().resolves(
      sid: "SM1234567",
    );
    sinon.stub(twilioMock, "messages").get(() => (
      create: createStub,
    ));
    const message = await twilioMock.messages.create(
      to: "blah",
      from: "blah",
      body: "hello",
    );
    expect(message.sid).toEqual("SM1234567");
  );
);

上述测试在我的设置中通过了。

【讨论】:

尝试上述方法并得到错误 TypeError: twilioMock.stubs.messages.value is not a function @philnash 这很奇怪,我刚刚启动了一个项目来测试它,并且在 VS Code TypeScript 中没有问题,但是运行测试确实会出现同样的错误。我会调查的。 好的,用一个新想法编辑了我的答案。让我知道这是否适合您。 太棒了,它按预期工作。非常感谢@philnash。

以上是关于如何使用 sinon js/loopback testlab 模拟来自 twilio-node 的 messages.create() 方法的返回值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sinon 存根 new Date()?

使用 Sinon 进行单元测试:如何在回调中测试变量?

如何正确指定使用 ts-sinon 的模拟的两种类型?

如何使用 sinon 存根/模拟从“超类”复制的依赖项方法

如何使用 Sinon 存根 npm 包 `phin`

如何使用 Jest 和 Sinon 测试 Thunk 动作