我试图在wpf应用程序中测试我的viewmodels。我在我的viewmodel中执行一个包含确认对话框的方法。我需要运行所有的单元测试,以便每次打开这些对话框时都需要手动确认。C#wpf UnitTesting viewmodels
我的问题是有什么办法,我可以编程方式知道哪个方法有确认对话框,并以编程方式点击“确定”或“取消”?
我试图在wpf应用程序中测试我的viewmodels。我在我的viewmodel中执行一个包含确认对话框的方法。我需要运行所有的单元测试,以便每次打开这些对话框时都需要手动确认。C#wpf UnitTesting viewmodels
我的问题是有什么办法,我可以编程方式知道哪个方法有确认对话框,并以编程方式点击“确定”或“取消”?
对此的最佳解决方案可能不是尝试以编程方式单击“确定”或“取消”,而是防止在运行单元测试时创建对话框。
要做到这一点,你需要一个抽象用于获取用户确认,这样的事情:
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
也有框架,而无需创建这些假冒的实现随时编写你自己的类,但是对于那些简单的例子,你可能不需要它们。
非常感谢Daniel的回答。我会尝试试验你的建议并让你知道结果。 – 2015-04-11 18:07:26
你用什么代码来显示确认对话框? – 2015-04-06 19:50:47