如何处理XUnitTest中的Yes No DisplayAlert?

时间:2018-12-20 03:56:21

标签: c# xamarin xamarin.forms xunit

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”?

1 个答案:

答案 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问题相关的影响。提供正确模拟的依赖项后,即可将其注入测试对象中。

在生产中,可以将系统配置为使用依赖项服务将服务实现注入到依赖类中。