Jasmine报错:Expected spy unknown to have been called 含义咨询
刚上手Jasmine碰到这个报错太正常了,我给你掰扯清楚这个问题:
报错整体含义
这个错误本质是:你写了一个断言,要求验证某个间谍函数已经被调用,但Jasmine根本找不到你指定的那个间谍——它只能用unknown这个占位符来表示它识别不了的间谍,所以没法完成验证。
报错里的unknown到底指啥?
这里的unknown是Jasmine的默认提示,当它找不到你在断言里引用的间谍对象时,就会输出这个词。说白了就是:你以为自己已经给某个方法挂上间谍了,但实际上这个间谍要么没创建成功,要么在断言时你引用的根本不是那个间谍。
常见原因&解决办法
下面是几个最容易踩的坑,对应解决方式也给你列出来:
间谍挂载的对象不对
比如你要监控的是userService.fetchData方法,但你却写成了spyOn(window, 'fetchData')——这就相当于你把间谍挂错了地方,Jasmine自然找不到它。
正确做法:确保spyOn的第一个参数是方法所属的正确对象,第二个是方法名。示例:const userService = { fetchData: () => {} }; spyOn(userService, 'fetchData'); // 把间谍挂到正确对象上 userService.fetchData(); expect(userService.fetchData).toHaveBeenCalled(); // 断言正确引用间谍断言时用了原方法而非间谍
比如你先把原方法存到变量里,然后挂了间谍,但断言的时候却去验证原方法,这肯定不行——原方法根本不是间谍啊!
错误示例:const originalFetch = userService.fetchData; spyOn(userService, 'fetchData'); expect(originalFetch).toHaveBeenCalled(); // 错!这是原方法,不是间谍解决:直接引用挂载了间谍的对象上的方法,也就是
userService.fetchData来做断言。间谍被意外覆盖了
如果在挂完间谍后,你又给目标方法重新赋值了(比如userService.fetchData = () => {}),这会直接把Jasmine创建的间谍给覆盖掉,断言时自然找不到。
解决:测试过程中别随便修改被spy的方法,要是需要保留原方法逻辑,用spyOn(userService, 'fetchData').and.callThrough()这种链式调用就好。方法名拼写错误
别笑,这真的是高频坑!比如你spy的是fetchData,断言时写成了fetchDta,Jasmine找不到对应间谍,就会输出unknown。
解决:仔仔细细检查spyOn和断言里的方法名,确保完全一致。
内容的提问来源于stack exchange,提问作者Brad Parks

