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

如何在模拟AWS SDK时使用node-mocks-http?附Express路由测试代码

如何在AWS SDK模拟的Express路由测试中使用node-mocks-http

我来帮你梳理下怎么把node-mocks-http融入到你现有的测试流程里~它的核心作用是模拟HTTP请求和响应对象,不用启动实际服务器就能测试路由逻辑,和你当前用的aws-sdk-mock、sinon完全互补——一个管AWS服务模拟,一个管HTTP层模拟,互不冲突。

第一步:安装依赖

如果还没装node-mocks-http,先装一下:

npm install node-mocks-http --save-dev
# 或者用yarn
yarn add node-mocks-http --dev

第二步:改造测试用例(替换supertest)

你原来用supertest发起请求,现在换成node-mocks-http创建模拟的req和res对象,直接传给Express路由处理函数就行。下面是基于你提供的精简代码修改后的完整示例:

const AWS = require('aws-sdk-mock');
const AWS_SDK = require('aws-sdk');
const sinon = require('sinon');
const rewire = require('rewire');
const { createRequest, createResponse } = require('node-mocks-http');
const { expect } = require('chai'); // 换成你常用的断言库即可

AWS.setSDKInstance(AWS_SDK);

let server;
let sendEmailMock;

before(() => {
  // 保留你原有的AWS模拟逻辑
  sendEmailMock = sinon.stub().callsArgWith(1, null, 'All is well');
  AWS.mock('SES', 'sendEmail', sendEmailMock);
  
  // 用rewire加载你的Express应用
  server = rewire('../../../..');
});

after(() => {
  // 清理模拟,避免测试污染
  AWS.restore('SES', 'sendEmail');
  sendEmailMock.restore();
});

describe('POST:/feedback', () => {
  it('Returns 200 with a fully formed request', (done) => {
    // 1. 创建模拟请求对象:设置请求方法、路径、请求体、headers等
    const req = createRequest({
      method: 'POST',
      url: '/gethelp/api/v1/feedback', // 补全你的完整路由路径
      body: {
        email: 'user@example.com',
        message: 'This is a test feedback'
      },
      headers: {
        'Content-Type': 'application/json'
      }
    });

    // 2. 创建模拟响应对象:如果路由是异步的,需要绑定事件发射器
    const res = createResponse({
      eventEmitter: require('events').EventEmitter
    });

    // 3. 触发路由处理:两种方式可选
    // 方式一:如果能通过rewire拿到路由的处理函数(更精准)
    // const feedbackHandler = server.__get__('feedbackHandler'); // 假设你导出了这个处理函数
    // feedbackHandler(req, res);

    // 方式二:直接让Express应用处理模拟的req/res
    server(req, res);

    // 4. 监听响应结束事件,做断言
    res.on('end', () => {
      // 断言状态码
      expect(res.statusCode).to.equal(200);

      // 断言响应体(如果有返回内容)
      const responseData = JSON.parse(res._getData());
      expect(responseData.success).to.be.true; // 替换成你的实际响应结构

      // 断言AWS SES的sendEmail方法被正确调用
      expect(sendEmailMock.calledOnce).to.be.true;
      expect(sendEmailMock.firstCall.args[0].Destination.ToAddresses).to.include('user@example.com');

      done();
    });
  });
});

几个关键注意点

  1. 异步路由的处理:如果你的路由逻辑是异步的(比如调用SES发送邮件),一定要通过res.on('end')来监听响应完成,或者用async/await配合res.finish事件,不然断言会在路由执行完之前就跑了。
  2. 请求体解析:如果你的路由依赖body-parser中间件,node-mocks-http默认不会自动解析请求体。你可以要么在创建req时直接设置body(像示例里那样),要么手动调用body-parser的中间件:
    require('body-parser').json()(req, res, () => {});
    
  3. 测试隔离:记得在测试前后清理AWS的模拟和sinon stub,避免不同测试用例之间互相干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:19:39