2015-04-06 63 views
1

我试图在wpf应用程序中测试我的viewmodels。我在我的viewmodel中执行一个包含确认对话框的方法。我需要运行所有的单元测试,以便每次打开这些对话框时都需要手动确认。C#wpf UnitTesting viewmodels

我的问题是有什么办法,我可以编程方式知道哪个方法有确认对话框,并以编程方式点击“确定”或“取消”?

+0

你用什么代码来显示确认对话框? – 2015-04-06 19:50:47

回答

0

对此的最佳解决方案可能不是尝试以编程方式单击“确定”或“取消”,而是防止在运行单元测试时创建对话框。

要做到这一点,你需要一个抽象用于获取用户确认,这样的事情:

public interface IUserConfirmation 
{ 
    bool Confirm(string title, string message); 
} 

在你的命令的执行,方法,你只能用这种抽象而不是实际显示一个对话框:

public class ViewModel 
{ 
    private void MyCommandExecuted(object parameter) 
    { 
     if (this.confirmation.Confirm("Please confirm", "Are you sure you want to ...?") 
     { 
      ... 
     } 
    } 

现在你创建这个接口的两个实现:一是这实际上显示一个对话框,用户和另一个只返回一个预先配置的值。在您的主应用程序中,您使用“真实”对话框实现,并在您的单元测试中使用“假”实现。

为了做到这一点,你需要能够在您的视图模型通过构造“注入”不同的实现方式,例如:

public ViewModel(IUserConfirmation confirmation) 
{ 
    if (confirmation == null) 
     throw new ArgumentNullException("confirmation"); 

    this.confirmation = confirmation; 
} 

private readonly IUserConfirmation confirmation; 

这实际上就是所谓的“依赖注入一个众所周知的模式”。有可用的框架可以帮助您创建对象,但对于像这样的简单案例,它们不是必需的。

下面是两个实现可能看起来像:

public class MessageBoxUserConfirmation : IUserConfirmation 
{ 
    public bool Confirm(string title, string message) 
    { 
     return MessageBox.Show(title, message) == true; 
    } 
} 

public class TestUserConfirmation: IUserConfirmation 
{ 
    public bool Result { get; set; } 

    public bool Confirm(string title, string message) 
    { 
     return this.Result; 
    } 
} 

在单元测试中,使用这样的:

var confirmation = new TestConfirmation(); 
var viewModel = new ViewModel(confirmation); 

// simulate a user clicking "Cancel" 
confirmation.Result = false; 

viewModel.MyCommand.Execute(...); 

// verify that nothing happened 

也有框架,而无需创建这些假冒的实现随时编写你自己的类,但是对于那些简单的例子,你可能不需要它们。

+0

非常感谢Daniel的回答。我会尝试试验你的建议并让你知道结果。 – 2015-04-11 18:07:26