Mock返回Promise的方法时出现AssertionError: expected MethodToStub问题求助
问题:Promise Mock 导致断言失败(AssertionError)
我刚接触MEAN栈和Promise,编写测试代码时遇到断言失败问题,相关代码如下:
const promise = new Promise<Boolean>(() => {}); const testObject = mock(DB_DAO_object); when (testObject.getFlag('value1')).thenReturn(promise.then(()=>{return true;})); when (testObject.getFlag('value2')).thenReturn(promise.then(()=>{return false;})); ChaiTest.expect(await testObject.getFlag(value1)).to.be.true; ChaiTest.expect(await testObject.getFlag(value2)).to.be.false;
运行测试后报错:
1) Check if testObject works as expected. test promise mocking: AssertionError: expected MethodToStub{ …(4) } to be false at Context.<anonymous> (test/src/promise.test.ts:121:106)
问题分析
Pending状态的Promise是核心问题
你创建的promise是一个永远处于pending状态的Promise——因为Promise构造函数里没有调用resolve或reject方法。这导致promise.then(...)返回的新Promise也永远不会被resolve,await会一直处于等待状态,最终测试要么超时,要么Mock方法返回未预期的Stub对象(即报错中的MethodToStub)。Mock返回值的冗余包装
即便基础Promise正常resolve,你用promise.then()包装返回值的写法也是冗余的。测试Mock异步方法时,直接返回已resolved的Promise即可,无需依赖外部pending Promise。
修复方案
方案1:直接返回已resolved的Promise
这是最简且合理的写法,直接用Promise.resolve()生成完成状态的Promise:
const testObject = mock(DB_DAO_object); // 直接为不同参数返回对应结果的已resolved Promise when(testObject.getFlag('value1')).thenReturn(Promise.resolve(true)); when(testObject.getFlag('value2')).thenReturn(Promise.resolve(false)); // 注意:确保断言时传入的参数是字符串'value1'/'value2',避免参数不匹配 ChaiTest.expect(await testObject.getFlag('value1')).to.be.true; ChaiTest.expect(await testObject.getFlag('value2')).to.be.false;
方案2:复用可resolve的基础Promise(若有需求)
如果确实需要复用Promise基础逻辑,务必保证基础Promise会被resolve:
// 创建一个会正常resolve的基础Promise const basePromise = new Promise<boolean>((resolve) => { resolve(true); // 必须调用resolve,否则Promise永远pending }); const testObject = mock(DB_DAO_object); when(testObject.getFlag('value1')).thenReturn(basePromise); // 若需要返回false,直接生成新的resolved Promise即可 when(testObject.getFlag('value2')).thenReturn(Promise.resolve(false)); ChaiTest.expect(await testObject.getFlag('value1')).to.be.true; ChaiTest.expect(await testObject.getFlag('value2')).to.be.false;
额外注意事项
- 确保你使用的Mock库(如Sinon)支持返回Promise类型的Stub值,主流Mock库均支持该特性。
- 断言时传入的参数要和Mock时的参数完全一致(比如都是字符串
'value1'),否则Mock不会匹配,会返回默认的Stub对象。
内容的提问来源于stack exchange,提问作者po-cha-na-quar-hip
相关产品推荐
相关产品推荐

