gpt4 book ai didi

javascript - 如何使用 Jasmine 在单元测试中模拟 super.ngOnInit() ?如何在基类/父类方法上创建 spy 以仅覆盖派生/子类代码?

转载 作者:行者123 更新时间:2023-12-01 01:12:56 24 4
gpt4 key购买 nike

export class Parent implements OnInit {
ngOnInit(): void {
// huge amount of different services calls
}
}

export class Child extends Parent implements OnInit {
ngOnInit(): void {
super.ngOnInit();
// a few more functions
}
}

如何开发单元测试来覆盖 Child 的 ngOnInit 而不模拟 Parent ngOnInit 的所有服务功能?

我的尝试是这样的:

let child: Child;
const mockParent = {
ngOnInit: jasmine.createSpy('ngOnInit')
};
child = new Child(); // base object is created already
Object.getPrototypeOf(child) = jasmine.createSpy('Parent').and.callFake(() => mockParent); // so this doesn't work

最佳答案

有一个解决方案如何监视父类函数。

Parent.prototype.ngOnInit = jasmine.createSpy('ngOnInit');

但是该解决方案不够安全。让我们看一下示例:

class Mobile {
sport: string;

setSport(): void {
this.sport = 'Football';
}
}

describe('MobileClass', () => {
const mobile: Mobile = new Mobile();

it('#setSport', () => {
mobile.setSport();
expect(mobile.sport).toBe('Football');
});
});

class Desktop extends Mobile {
isFootball: boolean;

setSport(): void {
super.setSport();
this.isFootball = this.func(this.sport);
}

func(sp: string): boolean {
return sp === 'Football' ? true : false;
}
}

describe('DesktopClass', () => {
const desktop: Desktop = new Desktop();

it('#setSport', () => {
Mobile.prototype.setSport = jasmine.createSpy('setSport');
desktop.sport = 'Basketball';

desktop.setSport();
expect(Mobile.prototype.setSport).toHaveBeenCalled();
expect(desktop.isFootball).toBe(false);
});

it('#func', () => {
// 2 cases covered
...
});
});

上面我们窥探了 setSport 基类函数。两项测试均顺利通过。现在想象一下在基类中进行了一些更改,例如在基类及其单元测试中,“Football”常量更改为“Tennis”。在这种情况下,两个类的单元测试都将成功通过。

让我们拒绝基类模拟的想法。我们将有:

describe('DesktopClass', () => {
const desktop: Desktop = new Desktop();

it('#setSport', () => {
desktop.setSport();
expect(desktop.isFootball).toBe(true);
});
});

在第一种情况下,两个测试都通过了,但是如果我们在基类及其单元测试中将“足球”更改为“网球”,那么现在,桌面测试将失败。当大团队处理一个大型项目并在几个文件中进行更改但忘记其他文件时,这是很常见的错误,因为两个文件的单元测试都成功通过了。

最后我想引用这篇文章'Mocking is a code smell' by Eric Elliott特别是一些引言:

What is tight coupling?

Subclass coupling: Subclasses are dependent on the implementation andentire hierarchy of the parent class: the tightest form of couplingavailable in OO design.

What causes tight coupling?

Mutation vs immutability, Side-Effects vs purity/isolated side-effects, etc.

从某些 Angular 来看,保留基类调用违反了单元测试术语,并且可能需要对基类中使用的服务进行更多模拟。我们需要将这些模拟移动到单独的文件中以保持干燥。三思而后行,选择什么:更快、更简单的代码,还是针对错误的额外保险。

关于javascript - 如何使用 Jasmine 在单元测试中模拟 super.ngOnInit() ?如何在基类/父类方法上创建 spy 以仅覆盖派生/子类代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55005399/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com