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

