使用TestBed,我们能够为依赖注入提供的类创建模拟类。例如,MyButtonClass
可以访问ElementRef
和MyService
,因为它们是通过依赖注入实现的,所以我们可以覆盖它们。我遇到的问题是,为了编写Jasmine测试,我必须创建模拟类来覆盖不使用依赖注入进行访问的类的方法。Angular 2 TestBed,无依赖注入的模拟方法
在这种情况下,ScriptLoader.load
将在全局空间中加载ThirdPartyCheckout
。这意味着,当Jasmine读取订阅运营商内部的内容时它可能不可用。出于这个原因,我想嘲笑前者,然后是后者。或者也许有不同的方式来解决这个问题。
如果有人可以建议一种创建模拟类以覆盖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();
}));
});
我简单地在'beforeEach()'里面覆盖'ScriptLoader.load'并工作。谢谢。但是,你用'beforeEach'和'afterEach'所做的每一个'it'每次都会覆盖ScriptLoader.load并将它返回给一个空变量,对吗?那是什么意思?也许,我没有区分覆盖静态方法和为函数分配新函数的区别? – jayscript
只需重置它,以便您可以在每个测试中使用不同的方法。如果你想让所有测试都一样,你可以使用'beforeAll'和'afterAll'。请记住,静态方法与类保持一致,而不是实例。所以在这个测试中改变它会影响使用它的其他测试(文件)。所以我们希望在完成我们的测试之前将其重置为原始方法 –
_“我没有区分覆盖静态方法和为函数分配新函数的区别吗?” - 不确定覆盖是什么意思。我认为你指的是同样的东西 –