如何用Sinon测试链式函数调用?遇TypeError报错求助
解决Sinon Stub调用
getTime()时报错的问题 你遇到的这个错误原因很清晰:你的代码期望obj.getTimeSent()返回一个Date对象,然后调用它的.getTime()方法,但你当前的stub返回的是数字1——数字类型根本没有getTime()方法,所以必然会抛出TypeError。
正确的Stub写法
你需要让stub返回一个符合原方法返回类型的对象,这里有几种简单可行的方案:
方案1:返回真实的Date实例(推荐,最贴合原逻辑)
如果只是需要固定一个时间,直接用returns()返回一个预先创建好的Date对象即可,比callsFake()更简洁:
// 固定一个你需要的时间 const fixedTimestampDate = new Date('2024-05-20T12:00:00'); const timeStub = sandbox.stub(Obj, 'getTimeSent').returns(fixedTimestampDate);
这样obj.getTimeSent().getTime()就会返回这个固定Date对应的时间戳,完全符合原代码的调用逻辑。
方案2:返回自定义的模拟对象(灵活控制返回值)
如果你不想用真实的Date实例,只想模拟getTime()方法的返回结果,可以手动创建一个带有该方法的对象:
const mockDateObj = { getTime: () => 1716187200000 // 这里替换成你需要的时间戳数字 }; const timeStub = sandbox.stub(Obj, 'getTimeSent').returns(mockDateObj);
这种方式适合你需要精确控制getTime()返回值的场景,不需要依赖真实Date的逻辑。
方案3:用Sinon Fake Timers全局控制时间(进阶用法)
如果你的测试场景需要全局统一控制时间(比如多个地方用到Date),可以用Sinon的fake timers功能:
// 把全局时间固定到2024-05-20 sandbox.useFakeTimers(new Date('2024-05-20').getTime()); // 此时new Date()会返回固定的时间,直接返回它即可 const timeStub = sandbox.stub(Obj, 'getTimeSent').returns(new Date());
这种方式能让所有Date相关的操作都使用你指定的固定时间,适合复杂的时间相关测试。
为什么之前的代码会报错?
再回顾一下你的原stub代码:
const timeStub = sandbox.stub(Obj, 'getTimeSent').callsFake(() => { return 1 });
这里callsFake()确实会让stub调用你提供的函数,但你返回的1是一个Number类型,而原方法getTimeSent()的返回值是Date类型——两者的API完全不兼容,当后续代码尝试调用.getTime()时,自然会报错。
内容的提问来源于stack exchange,提问作者evereveron
相关产品推荐
相关产品推荐

