Sinon Stub异常:fs.readFileSync抛错时Stub未触发预期报错
问题修复方案
你的测试用例存在几个关键错误,导致执行失败,以下是修复后的代码和问题解析:
问题解析
- 未捕获的错误:调用
index.getFile(filePath)时,由于stub已设置为抛出错误,这行代码会直接抛出错误,而你的try块在调用之后,根本没起到捕获作用。 - 错误的函数调用:
const gFile = index.getFile(filePath)已经执行了getFile函数,gFile是它的返回值(此时已抛出错误,根本不会完成赋值),后续的gFile(error)完全是错误用法。 - 断言对象错误:你应该断言
getFile的调用行为会抛出错误,而非断言stub本身。Chai的to.throw()需要包裹一个函数引用,而非直接执行函数。 - 语法不完整:你的try/catch块缺少闭合大括号,语法本身存在问题。
修复后的测试代码
方案1:使用Chai的expect(() => ...).to.throw()(推荐)
这种写法更简洁,符合Chai的断言风格:
it('should throw an error if fs.readFileSync throws an error', () => { const errorMsg = 'some error message'; // Stub fs.readFileSync 使其抛出错误 const readFileSyncStub = sinon.stub(fs, 'readFileSync').throws(new Error(errorMsg)); const filePath = '/Project/test.js'; // 用箭头函数包裹getFile调用,让Chai捕获错误 expect(() => index.getFile(filePath)).to.throw(errorMsg); // 恢复stub,避免影响其他测试 readFileSyncStub.restore(); });
方案2:使用try/catch手动捕获
如果更倾向于手动捕获错误,正确写法如下:
it('should throw an error if fs.readFileSync throws an error', () => { const error = new Error('some error message'); const readFileSyncStub = sinon.stub(fs, 'readFileSync').throws(error); const filePath = '/Project/test.js'; let caughtError = null; try { // 在try块内执行getFile,才能捕获错误 index.getFile(filePath); } catch (err) { caughtError = err; } // 断言捕获到的错误与预期一致 expect(caughtError).to.exist; expect(caughtError.message).to.equal(error.message); // 恢复stub readFileSyncStub.restore(); });
额外注意事项
- 每次stub之后一定要调用
restore(),或者使用sinon的sinon.test包裹测试自动清理stub,防止不同测试用例之间的污染。 - 也可以用Mocha的钩子函数在
afterEach中统一恢复所有stub:
afterEach(() => { sinon.restore(); });
内容的提问来源于stack exchange,提问作者Sorina
相关产品推荐
相关产品推荐

