使用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'。請記住,靜態方法與類保持一致,而不是實例。所以在這個測試中改變它會影響使用它的其他測試(文件)。所以我們希望在完成我們的測試之前將其重置爲原始方法 –
_「我沒有區分覆蓋靜態方法和爲函數分配新函數的區別嗎?」 - 不確定覆蓋是什麼意思。我認爲你指的是同樣的東西 –