gpt4 book ai didi

unit-testing - Angular 2 TestBed,没有依赖注入(inject)的模拟方法

转载 作者:太空狗 更新时间:2023-10-29 18:26:28 25 4
gpt4 key购买 nike

使用 TestBed ,我们能够为依赖注入(inject)可用的类创建模拟类。例如,MyButtonClass 可以访问 ElementRefMyService,因为它们是通过依赖注入(inject)实现的,因此我们可以覆盖它们。我遇到的问题是,要编写 Jasmine 测试,我必须创建模拟类来覆盖无法通过依赖注入(inject)访问的类的方法。

在这种情况下,ScriptLoader.load 将在全局空间中加载 ThirdPartyCheckout。这意味着,当 Jasmine 读取订阅操作符中的内容时,它可能不可用。出于这个原因,我想先 mock 前者,然后再 mock 后者。或者也许有不同的方法来解决这个问题。

如果有人可以建议一种方法来创建模拟类来覆盖 ScriptLoader.load 方法和 ThirdPartyCheckout.configure 方法,那就太好了。

要测试的指令:

@Directive({
selector: '[myButton]'
})
export class MyButtonClass implements AfterViewInit {

private myKey: string;

constructor(private _el: ElementRef, private myService: MyService) {}

ngAfterViewInit() {
this.myService.getKey()
.then((myKey: string) => {
this.myKey = myKey;
ScriptLoader.load('https://thirdpartyurl.js', this._el.nativeElement)
.subscribe(
data => {
this.handeler = ThirdPartyCheckout.configure(<any>{
key: this.myKey
// etc
// and some methods go here
});
},
error => {
console.log(error);
}
);
});
}
}

测试代码如下:

@Component({
selector: 'test-cmp',
template: ''
})
class TestComponent {}

class mockMyService {
getKey() {
return Promise.resolve('this is a key in real code');
}
}

describe('myButton', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestComponent, MyButtonClass],
providers: [
{provide: MyService, useClass: mockMyService}
]
});
});

describe('ngAfterViewInit', fakeAsync(() => {
const template = '<div><div myButton></div></div>';
TestBed.overrideComponent(TestComponent, {set: {template: template}});
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
tick();
}));
});

最佳答案

函数是一等公民,你可以给它分配一个新函数

let originalFn;

beforeEach(() => {
originalFn = ScriptLoader.load;
});

afterEach(() => {
ScriptLoader.load = originalFn;
});

it('...', fakeAsync(() => {
ScriptLoader.load = (url, el: Element): Observable<string> => {
return Observable.of('HelloSquirrel');
};
...
}));

除此之外,您可能只想考虑使用 DI。使用 DI 的主要原因之一是为了更好的可测试性。对于 ScriptLoader 只需将方法设为非静态方法,对于第三方库只需为其创建抽象服务层即可。

关于unit-testing - Angular 2 TestBed,没有依赖注入(inject)的模拟方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39490379/

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