Plaese帮助我如何在XUnitTest中使用await DisplayAlert吗?
LoginPageViewModel代码:
public ICommand LogoutCommand;
public LoginPageViewModel()
{
LogoutCommand= new RelayCommand(LogoutExecution);
}
async void LogoutExecution()
{
result = await App.Current.MainPage.DisplayAlert("Alert!","Are you sure you want to logout?", "Yes", "No");
if (result)
{
//Code Execution
await LogOut();
}
}
XUnitTest代码:
public class LoginPageViewModelTest
{
LoginViewModel loginvm;
public LoginViewModelTest()
{
Xamarin.Forms.Mocks.MockForms.Init();
var app = new Mock<App>().Object;
app.MainPage = new Mock<Xamarin.Forms.ContentPage>().Object;
loginvm = new LoginPageViewModel();
}
[Fact]
public void LogoutCommandExecuted()
{
loginvm.LogoutCommand.Execute(null);
}
}
当我测试LogoutCommandExecuted时,点击此行后执行未完成。 “等待App.Current.MainPage.DisplayAlert”
请帮助我,如何在命令执行方法中执行“ App.Current.MainPage.DisplayAlert”?
答案 0 :(得分:2)
从设计角度来看,视图模型在进行DisplayAlert
调用时与UI问题紧密相关。
应该抽象出这些问题,以提供更好的灵活性,可测试性和可维护性。
利用依赖倒置原则
例如,创建一个抽象以表示所需的功能
public interface IDialogService {
Task<bool> DisplayAlert (String title, String message, String accept, String cancel);
//...other members
}
其实现基本上会包装实际的UI问题
public class DialogService : IDialogService {
public Task<bool> DisplayAlert (String title, String message, String accept, String cancel) {
return App.Current.MainPage.DisplayAlert(title,message, accept, cancel);
}
//...other members
}
视图模型将明确依赖于服务抽象。
此外,请尽量避免使用async void
(事件处理程序除外)
public class LoginPageViewModel : ViewModelBase {
private readonly IDialogService dialog;
public LoginPageViewModel(IDialogService dialog) {
LogoutCommand = new RelayCommand(LogoutExecution);
}
public ICommand LogoutCommand { get; private set; }
void LogoutExecution() {
logOut += onLogOut;
logOut(this, EventArgs.Empty);
}
private event EventHdnalder logOut = delegate { };
private async void onLogOut(object sender, EventArgs args) {
logOut -= onLogOut;
var result = await dialog.DisplayAlert("Alert!","Are you sure you want to logout?", "Yes", "No");
if (result) {
//Code Execution
await LogOut();
}
}
//...
}
假设没有其他紧密耦合的依赖关系,那么LoginPageViewModel
应该能够被隔离地测试,而不会引起与UI问题相关的影响。提供正确模拟的依赖项后,即可将其注入测试对象中。
在生产中,可以将系统配置为使用依赖项服务将服务实现注入到依赖类中。