You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest测试Mock Twilio短信创建函数报错:Cannot set properties of undefined

解决Twilio API测试中无法Mock短信创建函数的问题

错误原因

你遇到的TypeError: Cannot set properties of undefined (setting 'create'),核心问题是直接操作twilio模块本身的messages属性,但该属性并不存在。业务代码里实际是通过twilio(twilioAccountSid, twilioAuthToken)生成客户端实例client,再调用client.messages.create;而测试中你mock的是twilio模块的messages,和业务代码里的客户端实例完全不是同一个对象,自然会报错。


解决方案

1. 正确Mock Twilio客户端

使用Jest的jest.mock来mock整个twilio模块,让它返回一个模拟的构造函数,这样业务代码中生成的client就是可控的mock对象。修改server.test.js如下:

require('@babel/register')({
  presets: ['@babel/preset-env']
}); 
require('dotenv').config(); // 加载环境变量,确保测试中能获取TWILIO_PHONE_NUMBER

import request from 'supertest';
import app from './server.mjs'; 
import twilio from 'twilio';

// Mock Twilio模块,返回模拟的客户端构造函数
jest.mock('twilio', () => {
  const mockMessagesCreate = jest.fn().mockResolvedValue({ sid: 'some-message-sid' });
  const mockClient = {
    messages: {
      create: mockMessagesCreate
    }
  };
  return jest.fn(() => mockClient);
});

// 获取mock的客户端实例和create方法
const mockClient = twilio();
const mockCreate = mockClient.messages.create;

describe('Server endpoints', () => {
  it('should send a verification code via SMS (mocked)', async () => {
    mockCreate.mockClear(); // 重置mock调用记录,避免跨测试污染

    const response = await request(app)
      .post('/send-verification-code')
      .send({ formattedPhoneNumber: '+447720761143' });

    expect(response.status).toBe(200);
    expect(response.body).toHaveProperty('verificationCode');
    expect(mockCreate).toHaveBeenCalledWith({
      body: expect.stringContaining('verification code'),
      from: process.env.TWILIO_PHONE_NUMBER,
      to: '+447720761143',
    });
  });
});

2. 优化业务代码(可选但推荐)

原server.mjs中存在await和.then/.catch混用的问题,导致错误处理逻辑冗余,建议统一使用try/catch:

// 替换原send-verification-code端点代码
app.post('/send-verification-code', async (req, res) => {
  console.log('Endpoint reached: /send-verification-code');
  const { formattedPhoneNumber } = req.body;
  console.log('Received request with formattedPhoneNumber:', formattedPhoneNumber);

  try {
    const verificationCode = Math.floor(100000 + Math.random() * 900000);
    const message = await client.messages.create({
      body: `G-${verificationCode} is your Google verification code.`,
      from: twilioPhoneNumber,
      to: formattedPhoneNumber,
    });
    console.log('Twilio API call successful:', message.sid);
    console.log('Verification code:', verificationCode);
    res.json({ 
      sid: message.sid,
      verificationCode: verificationCode,
    });
  } catch (error) {
    console.error('Twilio API call error:', error.response ? error.response.data : error);
    res.status(500).json({ error: 'Internal Server Error' });
  }
});

内容的提问来源于stack exchange,提问作者Jake Matthews

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:27:08