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:
- Mock Express req/res objects: Endpoint handlers expect these objects, so we'll stub their key methods to assert behavior later.
- Stub
db.save: Replace the real database call with a Sinon stub that returns your desired 201 status. - 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.saveuses callbacks instead of Promises: UsecallsArgWithto 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
dbis a class instance: Usesinon.createStubInstanceto create a stubbed instance of your DB class, then inject it into your endpoint module (consider usingproxyquireto 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
相关产品推荐
相关产品推荐

