Jasmine框架下如何验证嵌套函数的toHaveBeenCalledTimes(9)调用次数
单元测试method3调用次数失败解决方案
问题原因
共有4个错误点共同导致断言失败:
spyOn语法使用错误
Jasmine的spyOn要求第一个参数为方法所属的宿主对象,第二个参数为方法名的字符串格式,你直接传入component.method1的写法不符合API规范;同时callThrough是可执行方法,必须加括号调用才会生效,未调用时spy会默认替换原方法为空函数,不会执行真实逻辑。- 内部方法调用指向错误
原业务代码中method1内直接调用method2(event),默认指向全局作用域下的method2函数,和你挂载在component实例上被spy监听的method2不是同一个函数,因此spy监听不到内部调用,也不会触发后续method3执行。 - 业务代码判断条件错误
input是DOM对象本身没有length属性,你写的input.length < 9判断条件永远为假,method3永远不会被触发,需要改为读取input.value.length。 - 前置状态未初始化
如果测试运行前input.value已有内容,初始长度超过9的情况下method3自然不会被调用。
解决步骤
1. 修正业务代码
function method1( event ) { // 调用实例自身挂载的method2 this.method2(event); } function method3( event ) { input.value += event.key; } function method2(event) { // 修正判断条件,读取input.value的长度 if (input.value.length < 9) // 调用实例自身挂载的method3 this.method3(event); }
2. 修正测试代码
it("method3 should be called 9 times",() => { // 测试前重置input状态,确保初始值为空 input.value = ''; // 修正spyOn的正确写法 spyOn(component, 'method1').and.callThrough(); spyOn(component, 'method2').and.callThrough(); spyOn(component, 'method3').and.callThrough(); for (var i = 0; i < 20; i++) { component.method1(new KeyboardEvent('keydown', {key:'1'})); } expect(component.method1).toHaveBeenCalledTimes(20); expect(component.method2).toHaveBeenCalledTimes(20); expect(component.method3).toHaveBeenCalledTimes(9); });
内容的提问来源于stack exchange,提问作者Sabila2022
相关产品推荐
相关产品推荐

