单元测试没跑通过
在跑单元测试的时候遇到了这个问题, 控制台报错:
An error was thrown in afterAll
Uncaught undefined thrown
浏览器:
1.由于没有报错组件的位置,当时第一时间想到的是,可能在某个单元测试afterAll()方法中,出现了问题。于是用全局搜索:afterAll。 但是并没有找到该关键字。
2.同时在mingao的电脑上,同样的代码,他那里跑单元测试并不会出现该问题。 只有我这里以及机器人跑的时候有这个问题。
3.之后也去之前的项目中找了afterAll 关键字, 也没有找到。
4.谷歌之后,发现有人遇到和我一样的问题,只不过我的是undefind. 他的是object.
尝试一
显示第一的是一个100多赞的答案,他说声明了两个beforeEach, 会造成竞争情况,导致运行失败。所以他把两个beforeEach 合并成同步了。
先简单描述async。
async函数的本质就是返回了一个promise对象,在这个函数里里我们加上await后,即使调用的是异步代码,它也会变成类似于同步,只有让这个异步代码执行完后,才会执行下面的同步代码来执行。
首先不说是否能解决问题。 实际上,合并与不合并,只是angular官方推荐的两种不同的设置:
1.分开设置:
2.组合设置:
所以这只是两种不同的写法。
我估计他只是,忘了写await了,导致两个beforeEach同步执行了。
研究了一下这种方法,最终不起作用。
尝试二
第二个答案:
在单元测试中添加这个: 在每个单元测试后销毁夹具
afterEach(() => {
fixture.destroy();
});
由于是跑全局单元测试时报的错,所以我并不知道在哪个单元测试中添加这个项。
好在目前组件并不算多,于是我挨个尝试了一下。
最后在menu.component组件中添加了该项后。单元测试没有再报错。
研究原因:
注意到该组件和别的地方不一样的是, 添加了teardown: { destroyAfterEach: false }
之前也介绍过:
angular13 新版本中每次测试的时候会清理DOM, 该项默认为true。 设置为false之后我们可以在fit下, 观察到v层的变化。 否则看见的是空白。
所以我猜想是设置了destroyAfterEach: false 才导致的上面的报错。
于是我删除了teardown: { destroyAfterEach: false } 和
afterEach(() => {fixture.destroy();})
再进行测试。
结果和想象中的一样,没有报错。
所以结论出来了:目前使用 teardown: { destroyAfterEach: false }, 需要 同时使用afterEach(() => {fixture.destroy();}) 来销毁夹具。
但令我疑惑的是,其实之前只单单使用了destroyAfterEach: false, 当时并没有报错。 本文中的报错其实是在前几天才发现。 可能还受到其他的一些因素影响。
ngmodel在fromGroup下需要添加standalone
这个报错说明的很清楚,ngmodel不能用于fromGroup下。 若需要使用,需要添加:[ngModelOptions] = "standalone: true"
添加之后运行成功.
第三方标签不适配fromControl
在开发 角色选择组件 的时候控制台发现了如下的报错。
后来经过排查后发现,是因为使用fromControl绑定了第三方标签thy-custom-select的问题。
在官方的文档中,使用示例用的是[(ngModel)] = ""
来绑定变量。
但是经过多次测试之后,若使用[fromControl]=""
绑定, 则会出现如上的报错。
后来只能改一下角色选择组件。
选择ngModel控制变量。ngModelChange($event)来接收变量的改变。
总的来说和以前相比,即是多了一个变量,来作为中间变量控制fromControl
以下代码前面带+号的为新增
export class UserRoleSelectComponent implements OnInit, ControlValueAccessor {
selected = new FormControl;
+ roleType!: RoleType;
registerOnChange(fn: any): void {
this.selected.valueChanges
.subscribe(data => fn(data));
}
registerOnTouched(fn: any): void {
}
writeValue(obj: number): void {
this.selected.setValue(obj);
+ this.roleType = obj as RoleType;
}
+ ngModelChange($event : RoleType) {
+ this.selected.setValue($event);
+ }
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。