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

Node Express测试:如何用Mocha、Sinon Stub内部依赖db.save

Got it! Let's walk through how to stub your db.save call with Sinon so it returns a 201 status code for your Express endpoint tests. First, I'll assume your endpoint module looks something like this (adjust if your actual code differs):

// endpoints.js
const db = require('./db');

exports.createResource = async (req, res) => {
  try {
    const operationResult = await db.save(req.body);
    res.status(operationResult.statusCode).json(operationResult.data);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
};

Step-by-Step Implementation

First, make sure your test file imports all the necessary tools: Mocha, Chai (I'll use expect here), Sinon, your endpoint module, and the db module it depends on. Then follow these steps:

  1. Mock Express req/res objects: Endpoint handlers expect these objects, so we'll stub their key methods to assert behavior later.
  2. Stub db.save: Replace the real database call with a Sinon stub that returns your desired 201 status.
  3. Clean up stubs: Ensure each test starts fresh by restoring stubs after each run.

Here's the complete test code:

// endpoints.test.js
const { expect } = require('chai');
const sinon = require('sinon');
const db = require('./db');
const endpoints = require('./endpoints');

// Mock Express request and response objects
const mockReq = { body: { name: 'test resource', value: 'foo' } };
const mockRes = {
  status: sinon.stub().returnsThis(), // Allow chaining (res.status(...).json(...))
  json: sinon.stub()
};

describe('createResource endpoint', () => {
  let saveStub;

  // Create stub before each test
  beforeEach(() => {
    // Stub db.save to resolve with a 201 status code and sample data
    saveStub = sinon.stub(db, 'save').resolves({
      statusCode: 201,
      data: { id: 123, name: 'test resource', value: 'foo' }
    });
  });

  // Restore original db.save after each test to avoid cross-test contamination
  afterEach(() => {
    saveStub.restore();
  });

  it('should return 201 status when db.save succeeds', async () => {
    // Execute the endpoint handler
    await endpoints.createResource(mockReq, mockRes);

    // Assert db.save was called with the correct request body
    expect(saveStub.calledWith(mockReq.body)).to.be.true;
    // Assert the response status was set to 201
    expect(mockRes.status.calledWith(201)).to.be.true;
    // Optional: Assert the response JSON matches the stubbed data
    expect(mockRes.json.calledWith({ id: 123, name: 'test resource', value: 'foo' })).to.be.true;
  });
});

Key Notes for Edge Cases

  • If db.save uses callbacks instead of Promises: Use callsArgWith to trigger the callback with your 201 result:
    saveStub = sinon.stub(db, 'save').callsArgWith(1, null, { statusCode: 201, data: {...} });
    // (1 = index of the callback argument; null = no error)
    
  • If db is a class instance: Use sinon.createStubInstance to create a stubbed instance of your DB class, then inject it into your endpoint module (consider using proxyquire to avoid modifying production code):
    const proxyquire = require('proxyquire');
    const Db = require('./db');
    const dbStub = sinon.createStubInstance(Db);
    dbStub.save.resolves({ statusCode: 201, data: {...} });
    
    // Replace the real db module with our stubbed instance
    const endpoints = proxyquire('./endpoints', { './db': dbStub });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:15:35