Unit testing 如何模拟DialogService.open(…)。何时用Jasmine关闭(…)?
我们有一些使用Aurelia框架和对话框插件的TypeScript代码,我们正试图用Jasmine测试这些代码,但无法解决如何正确执行 这是源函数:Unit testing 如何模拟DialogService.open(…)。何时用Jasmine关闭(…)?,unit-testing,aurelia,aurelia-dialog,Unit Testing,Aurelia,Aurelia Dialog,我们有一些使用Aurelia框架和对话框插件的TypeScript代码,我们正试图用Jasmine测试这些代码,但无法解决如何正确执行 这是源函数: openDialog(action: string) { this._dialogService.open({ viewModel: AddAccountWizard }) .whenClosed(result => { if (!result.wasCancelled && r
openDialog(action: string) {
this._dialogService.open({ viewModel: AddAccountWizard })
.whenClosed(result => {
if (!result.wasCancelled && result.output) {
const step = this.steps.find((i) => i.action === action);
if (step) {
step.isCompleted = true;
}
}
});
}
我们可以创建一个DialogService spy,并轻松地验证open方法,但我们无法解决如何让spy使用模拟结果参数调用whenClosed方法,以便我们可以断言该步骤已完成
这是当前的Jasmine代码:
it("opens a dialog when clicking on incomplete bank account", async done => {
// arrange
arrangeMemberVerificationStatus();
await component.create(bootstrap);
const vm = component.viewModel as GettingStartedCustomElement;
dialogService.open.and.callFake(() => {
return { whenClosed: () => Promise.resolve({})};
});
// act
$(".link, .-arrow")[0].click();
// assert
expect(dialogService.open).toHaveBeenCalledWith({ viewModel: AddAccountWizard });
expect(vm.steps[2].isCompleted).toBeTruthy(); // FAILS
done();
});
我们最近刚刚更新了DialogService,遇到了同样的问题,所以我们制作了这个基本的模拟,到目前为止它符合我们的目的。它相当有限,不适合模拟具有不同结果的多个调用,但适用于上述情况:
export class DialogServiceMock {
shouldCancelDialog = false;
leaveDialogOpen = false;
desiredOutput = {};
open = () => {
let result = { wasCancelled: this.shouldCancelDialog, output: this.desiredOutput };
let closedPromise = this.leaveDialogOpen ? new Promise((r) => { }) : Promise.resolve(result);
let resultPromise = Promise.resolve({ closeResult: closedPromise });
resultPromise.whenClosed = (callback) => {
return this.leaveDialogOpen ? new Promise((r) => { }) : Promise.resolve(typeof callback == "function" ? callback(result) : null);
};
return resultPromise;
};
}
此模拟可以配置为在用户取消对话框时测试各种响应,以及对话框仍然打开的场景
我们还没有完成e2e测试,因此我不知道有什么好方法可以确保您等到.click()调用完成,这样您就不会在expect()和whenClosed()逻辑之间存在竞争条件,但我认为您应该能够在测试中使用模拟,如下所示:
it("opens a dialog when clicking on incomplete bank account", async done => {
// arrange
arrangeMemberVerificationStatus();
await component.create(bootstrap);
const vm = component.viewModel as GettingStartedCustomElement;
let mockDialogService = new MockDialogService();
vm.dialogService = mockDialogService; //Or however you're injecting the mock into the constructor; I don't see the code where you're doing that right now.
spyOn(mockDialogService, 'open').and.callThrough();
// act
$(".link, .-arrow")[0].click();
browser.sleep(100)//I'm guessing there's a better way to verify that it's finished with e2e testing, but the point is to make sure it finishes before we assert.
// assert
expect(mockDialogService.open).toHaveBeenCalledWith({ viewModel: AddAccountWizard });
expect(vm.steps[2].isCompleted).toBeTruthy(); // FAILS
done();
});
谢谢,我们在几个方面改进了这个场景。我们停止使用whenClosed()API,并将所有DialogService调用转换为使用open和close结果承诺,以便这些方法变得完全异步。在测试中调用VM方法时,我们使用wait,而不是使用按钮单击。如果我们想测试按钮单击是否已连接,我们可以在一个单独的测试中执行该操作,该测试监视VM方法以断言它已被调用。在处理断言之前,我们还使用aurelia框架中的TaskQueue组件等待处理所有其他副作用。@Sam,我知道已经有一段时间了,但是,当关闭API时,您是如何摆脱
的呢?我正在尝试async/wait
dialogService.open
调用,但到目前为止没有任何效果。