我有一个抽象类,可以帮助避免重复代码(取消订阅可观察对象),它看起来像:
export abstract class SubscriptionManagmentDirective implements OnDestroy {
componetDestroyed = new Subject<void>()
constructor() {}
ngOnDestroy(): void {
this.componetDestroyed.next()
this.componetDestroyed.unsubscribe()
}
}
在某些情况下,我重写了ngOnDestroy
,忘记调用super.ngOnDestroy()
,然后订阅就疯狂了。我向扩展组件添加了一个单元测试,以测试取消订阅是否被调用,但要这样做,我实际上必须记住添加它们。
我的问题是,
- 是否有一种方法来强制
super.ngOnDestroy()
被调用每当组件被扩展? - 或者是否有一种方法可以为抽象类编写单元测试,该抽象类可以在扩展该类的任何组件上进行测试?
请帮忙,谢谢。
我认为最好的方法是将"noImplicitOverride": true
添加到tsconfig中。它不一定会帮助您记住调用超级方法,但它会迫使您明确地重写方法,在未使用override
关键字的情况下重写方法时抛出编译错误。然后由开发人员决定是否需要调用父方法。
https://www.typescriptlang.org/tsconfig noImplicitOverride
-
不,没有这样的方法可以从抽象中自动调用方法。
-
您必须单独进行单元测试。只需创建一个扩展抽象的内联测试类,然后对
ngOnDestroy
进行单元测试。这就够了。
我只能想到一种方法,非常粗糙和丑陋。被强制执行的一件事是构造函数中的super()
调用,由TypeScript自己执行。因此你可以
class Foo {
constructor() {
const oldNgOnDestroy = this.ngOnDestroy;
this.ngOnDestroy = function() {
console.log("decorated ngOnDestroy");
return oldNgOnDestroy();
}.bind(this);
}
ngOnDestroy() {
console.log("original ngOnDestroy");
}
}
class Bar extends Foo {
constructor() {
super();
}
}
class Baz extends Foo {
constructor() {
super();
}
ngOnDestroy() {
console.log("custom ngOnDestroy");
}
}
const bar = new Bar();
bar.ngOnDestroy();
const baz = new Baz();
baz.ngOnDestroy();
就像我说的,又丑又丑。