Как имитировать возвращаемое значение метода messages.create() из twilio-узла с помощью sinon js/loopback testlab?

#node.js #unit-testing #mocking #twilio #sinon

Вопрос:

Я пытаюсь высмеять возвращаемое значение метода messages.create() из библиотеки twilio-узлов.

Поскольку метод create находится внутри интерфейса, называемого сообщениями, я не могу напрямую имитировать возвращаемое значение метода 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 это геттер и динамически определяется. Итак, я напрямую вставил результат в клиент-заглушку.

 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");
  });
});
 

Вышеуказанный тест проходит для меня в моей настройке.

Комментарии:

1. Попробовал вышесказанное и получил ошибку TypeError: twilioMock.stubs.messages.значение не является функцией @philnash

2. Это странно, я только что запустил проект, чтобы проверить это, и в VS Code TypeScript нет проблем, но запуск теста приводит к той же ошибке. Я займусь этим вопросом.

3. Хорошо, отредактировал свой ответ с новой идеей. Дай мне знать, если это сработает для тебя.

4. Потрясающе, все работает так, как ожидалось. Большое вам спасибо @philnash.