我的 Angular/Karma 測驗存在覆寫問題。
我創建了一個具有 signUp() 函式的組件
angularFireAuthSignOutSpyObj是組件中this.auth的間諜(Firebase Auth)
signUp() {
if (this.registrationForm.valid) {
this.auth.createUserWithEmailAndPassword
(
this.registrationForm.get('email')?.value,
this.registrationForm.get('password')?.value
)
.then(() => {
this.appMessage = "Account created !";
})
.catch((error) => {
this.appMessage = error.message;
});
} else {
this.appMessage = 'Submit logic bypassed, form invalid !'
}
}
我正在使用業力測驗來測驗這個組件功能
it('should submit registration with form values', () => {
spyOn(component, 'signUp').and.callThrough();
angularFireAuthSignOutSpyObj.createUserWithEmailAndPassword.and.returnValue({
then: function () {
return {
catch: function () {
}
};
}
});
component.registrationForm.controls.email.setValue('[email protected]');
component.registrationForm.controls.password.setValue('ValidPass123');
component.registrationForm.controls.passwordCheck.setValue('ValidPass123');
expect(component.registrationForm.valid).toBeTruthy();
debugElement.query(By.css("button")).triggerEventHandler("click", null);
expect(component.signUp).toHaveBeenCalled();
expect(component.auth.createUserWithEmailAndPassword)
.toHaveBeenCalledWith(
component.registrationForm.controls.email.value,
component.registrationForm.controls.password.value)
// expect(component.appMessage).toEqual('Account created !');
});
如您所見,最后一個期望被注釋掉,因為它回傳錯誤:預期未定義等于“創建帳戶!”。 這是因為即使this.auth.createUserWithEmailAndPassword在模擬服務angularFireAuthSignOutSpyObj 中定義,并且使用 2 個預期引數正確呼叫,我也無法控制定義的then和catch函式。
They are defined so it won't trigger an error when trying to access it in the signUp() function. But what I would like to do is trigger the then(() => ...) and the catch(() => ...) so I can test/check that the app.message was correctly updated.
All the exceptions work until the last one. I feel like that I need to modify something in my createUserWithEmailAndPassword.and.returnValue to probably return something that triggers the then or the catch.
angularFireAuthSignOutSpyObj.createUserWithEmailAndPassword.and.returnValue({
then: function () {
return {
catch: function () {
}
};
}
});
Anyone has an idea on how I could test the actual auth.createUserWithEmailAndPassword result behaviour of my component ?
Thanks very much !
David
uj5u.com熱心網友回復:
我沒有看到您創建間諜的代碼。你使用 Promise 而不是 Observables 也有點奇怪。但是,我會調查監視方法——而不是類,并回傳一個你控制的承諾:
const resolveFunction;
const rejectFunction;
beforeEach(() => {
spyOn(component.auth, 'createUserWithEmailAndPassword').and.returnValue(new Promise((resolve, reject) => {
resolveFunction = resolve;
rejectFunction = reject;
})
}
現在從您的測驗中,您可以通過呼叫這些函式來控制何時拒絕或解決承諾:
it('test catch block', () => {
// some code
rejectFunction('some error object');
})
it('test then block', () => {
// some code
resolveFunction('some error object');
})
有關手動創建承諾的更多資訊
uj5u.com熱心網友回復:
嘿,我只是想發布更新,因為我設法完成了我需要的作業。感謝@JeffryHouser 的提醒。
所以基本上我的組件最初期望來自查詢的Promise。如果結果恢復正常(UserCredentials),我們只需使用成功訊息更新 appMessage 字串。如果沒有(捕獲),我們將回傳錯誤訊息。
這些是我在測驗端所做的更改,以模擬決議(承諾的正常結果,以及如何觸發捕獲)
- 使用fakeAsync()將測驗設定為異步
- 監視用戶 click() 使用的每個函式
- 為angularFireAuthSignOutSpyObj.createUserWithEmailAndPassword函式指定回傳作為 Promise
- 使用tick()模擬異步流程
- 使用fixture.detectChanges()檢測promise流程結束后的變化
appMessage 專案按照流程正確更新
這是代碼!
間諜宣告
let angularFireAuthSignOutSpyObj: jasmine.SpyObj<any>;
...
beforeEach(async () => {
angularFireAuthSignOutSpyObj = jasmine.createSpyObj('AngularFireAuth',
['createUserWithEmailAndPassword']);
...
});
用戶憑證項
//Only setting the fields needed
export const testUserCredentials: UserCredential = {
user: {
providerData: [
{
email: '[email protected]',
}
]
}
}
測驗
it('should submit registration with form values', fakeAsync(() => {
spyOn(component, 'signUp').and.callThrough();
angularFireAuthSignOutSpyObj.createUserWithEmailAndPassword.and.callFake(() => new Promise(
resolve => {
resolve(testUserCredentials);
})
);
component.registrationForm.controls.email.setValue('[email protected]');
component.registrationForm.controls.password.setValue('ValidPass123');
component.registrationForm.controls.passwordCheck.setValue('ValidPass123');
expect(component.registrationForm.valid).toBeTruthy();
debugElement.query(By.css("button")).triggerEventHandler("click", null);
expect(component.signUp).toHaveBeenCalled();
expect(component.auth.createUserWithEmailAndPassword)
.toHaveBeenCalledWith(
component.registrationForm.controls.email.value,
component.registrationForm.controls.password.value)
tick();
fixture.detectChanges();
expect(component.appMessage).toEqual('Account created : [email protected]');
}));
如何觸發錯誤而不是解決
angularFireAuthSignOutSpyObj.createUserWithEmailAndPassword.and.callFake(() => new Promise(() => {
throw {message: 'test purpose failure'};
}));
更新了 register.component.ts
signUp() {
if (this.registrationForm.valid) {
let createdEmail: string | null | undefined;
this.auth.createUserWithEmailAndPassword
(
this.registrationForm.get('email')?.value,
this.registrationForm.get('password')?.value
)
.then((userCredential: UserCredential) => {
userCredential?.user?.providerData?.forEach(userInfo => {
createdEmail = userInfo?.email;
})
this.appMessage = "Account created : " createdEmail;
})
.catch((error) => {
this.appMessage = "Account creation failed : " error.message;
});
} else {
this.appMessage = 'Submit logic bypassed, form invalid !'
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/317099.html
