Angular异步Promise单元测试:非inbound callType分支测试问题
Angular
searchObject 方法非inbound分支单元测试实现方案 原有测试失败的核心问题
- 入参错误:测试非inbound场景时,传入参数的
callType仍然赋值为'inbound',根本不会进入目标分支 - 业务逻辑特性:当前待测试代码中,仅当
callType === 'inbound'时才会执行sforce.opencti.searchAndScreenPop调用,并在回调中触发Promise的resolve/reject;其余callType场景下没有任何resolve/reject逻辑,返回的Promise会持续处于pending状态,无法直接用toBeResolved/toBeRejected做状态断言 - 断言逻辑冲突:原测试代码既mock了
searchAndScreenPop的失败回调,又断言该方法从未被调用,逻辑自相矛盾
正确的非inbound分支测试用例
针对当前业务代码的逻辑,非inbound分支只需要验证核心行为:不会触发Salesforce的searchAndScreenPop方法,且Promise不会异常落定,参考实现如下:
it('should not trigger searchAndScreenPop when callType is not inbound', () => { // 给searchAndScreenPop加spy,调用即抛错,方便检测非法调用 sforce.opencti.searchAndScreenPop = jasmine.createSpy().and.throwError('should not be called for non-inbound callType'); // 传入outbound类型参数,注意不要await这个Promise,否则会因为pending超时 const resultPromise = service.searchObject({ searchValuesString: 'value1&&value2', callType: 'outbound' // 必须传非inbound的值才能进入目标分支 } as any); // 验证核心搜索方法未被调用 expect(sforce.opencti.searchAndScreenPop).not.toHaveBeenCalled(); // 验证Promise处于pending状态,没有被意外resolve或reject expectAsync(resultPromise).toBePending(); });
额外注意事项
- 如果后续业务迭代补全了非inbound分支的逻辑(比如适配outbound场景的搜索逻辑、或者直接返回默认值),需要对应补充Promise落定状态的断言
- 测试非inbound场景时不要加
await等待Promise返回,否则会因为Promise一直pending触发Jasmine测试超时 - 若使用的Jasmine版本低于3.6,不支持内置
toBePending匹配器,可以用以下写法替代pending状态断言:// 低版本Jasmine pending状态校验 const pendingCheck = Promise.race([ resultPromise, new Promise((_, reject) => setTimeout(() => reject('pending'), 50)) ]).then(() => false, () => true); expectAsync(pendingCheck).toBeResolvedTo(true); - 原有inbound分支的测试用例逻辑正确,可以保留覆盖入站场景的成功/失败逻辑
内容的提问来源于stack exchange,提问作者Ciprian Grumăzescu
相关产品推荐
相关产品推荐

