【问题标题】:Jest mock twilio - how to?开玩笑模拟 twilio - 如何?
【发布时间】:2020-10-20 05:34:03
【问题描述】:

我一直在使用 Jest 对 node 进行单元测试。

我习惯于模拟第一级的模块/函数,但是在模拟 Twilio 的挑战中,我没有那么幸运。

我使用的是twilio方法:client.messages.create,所以这里我有来自构造函数require('twilio')(account sid, token)的twilio客户端,第一层来自对象/方法(?)messages,最后是第三层create,这是我要嘲笑的最后一个人。

我正在尝试这样的事情:

jest.mock('twilio', () => {
  const mKnex = {
    messages: jest.fn(),
  };
  return jest.fn(mKnex);
});

但是,我无法模拟 client 解析的值,我得到 client.message.create is not a function。 如果我尝试上面的模拟加上这个client.messages.create.mockReturnValueOnce({sid: "FOO", status: "foo");,我会发现无法从undefined(消息)读取属性create

任何提示、帖子、文档可以让我在这方面获得一些运气吗? 谢谢

【问题讨论】:

    标签: unit-testing jestjs twilio


    【解决方案1】:

    解决办法是:

    1. 为 Twilio 客户端创建文件:
    // sms.client.ts
    
    import { Twilio } from 'twilio';
    
    const smsClient = new Twilio(
      'TWILIO-ACCOUNT-SID',
      'TWILIO-TOKEN'
    );
    
    export { smsClient };
    
    
    1. 然后,您的服务文件应如下所示:
    // sms.service.ts
    
    import { smsClient } from './sms.client';
    
    class SMSService {
      async sendMessage(phoneNumber: string, message: string): Promise<string> {
        const result = await smsClient.messages.create({
          from: '(555) 555-5555',
          to: phoneNumber,
          body: message,
        });
    
        if (result.status === 'failed') {
          throw new Error(`Failed to send sms message. Error Code: ${result.errorCode} / Error Message: ${result.errorMessage}`);
        }
    
        return result.sid;
      }
    }
    
    export const smsService = new SMSService();
    
    
    1. 最后但同样重要的是,您的规范/测试文件需要模拟客户端文件。例如
    // sms.service.spec.ts
    
    import { MessageInstance, MessageListInstance } from 'twilio/lib/rest/api/v2010/account/message';
    import { smsClient } from './sms.client';
    import { smsService } from './sms.service';
    
    // mock the client file
    jest.mock('./sms.client');
    
    // fixture
    const smsMessageResultMock: Partial<MessageInstance> = {
      status: 'sent',
      sid: 'AC-lorem-ipsum',
      errorCode: undefined,
      errorMessage: undefined,
    };
    
    describe('SMS Service', () => {
      beforeEach(() => {
        // stubs
        const message: Partial<MessageListInstance> = {
          create: jest.fn().mockResolvedValue({ ...smsMessageResultMock })
        };
        smsClient['messages'] = message as MessageListInstance;
      });
    
      it('Should throw error if response message fails', async () => {
        // stubs
        const smsMessageMock = {
          ...smsMessageResultMock,
          status: 'failed',
          errorCode: 123,
          errorMessage: 'lorem-ipsum'
        };
        smsClient.messages.create = jest.fn().mockResolvedValue({ ...smsMessageMock });
    
        await expect(
          smsService.sendMessage('(555) 555-5555', 'lorem-ipsum')
        ).rejects.toThrowError(`Failed to send sms message. Error Code: ${smsMessageMock.errorCode} / Error Message: ${smsMessageMock.errorMessage}`);
      });
    
      describe('Send Message', () => {
        it('Should succeed when posting the message', async () => {
          const resultPromise = smsService.sendMessage('(555) 555-5555', 'lorem-ipsum');
          await expect(resultPromise).resolves.not.toThrowError(Error);
          expect(await resultPromise).toEqual(smsMessageResultMock.sid);
        });
      });
    });
    
    

    【讨论】:

      【解决方案2】:

      我找到了解决方案。它仍在调用端点,但是对于每个 twilio 帐户,您都会获得一个测试 SID 和令牌,我使用了这个,因此在使用它进行测试时它不会发送短信:

      if (process.env.NODE_ENV !== 'test') {
          client = require('twilio')(accountSid, authToken)
          listener = app.listen(3010, function(){
              console.log('Ready on port %d', listener.address().port)
          })
      }else{
          client = require('twilio')(testSid, testToken)
      }
      

      【讨论】:

      • 投反对票,因为它在模拟 Twilio 时不能解决问题。如果我们想测试不同的案例场景怎么办?
      猜你喜欢
      • 2020-11-18
      • 1970-01-01
      • 2018-07-25
      • 2020-08-20
      • 2020-05-27
      • 2018-05-05
      • 2021-05-27
      • 2022-01-24
      • 1970-01-01
      相关资源
      最近更新 更多