C# 如何对WPF用户控件的视图模型进行单元测试
如何在C# 如何对WPF用户控件的视图模型进行单元测试,c#,wpf,silverlight,mvvm,moq,C#,Wpf,Silverlight,Mvvm,Moq,如何在ChildrenViewModel中模拟创建ChildViewModels: IChildViewModel c = new ChildViewModel(child); children.Add(c); 我使用的是ChildViewModel(没有ChildView!),因为Child(model)类没有实现INotifyPropertyChangedUPDATE:我引入封装子对象的ChildViewModel的原因之一是验证需求域模型对象应始终有效(例如,孩子的名字不得包含数字)。但
ChildrenViewModel
中模拟创建ChildViewModel
s:
IChildViewModel c = new ChildViewModel(child);
children.Add(c);
我使用的是ChildViewModel
(没有ChildView
!),因为Child
(model)类没有实现INotifyPropertyChanged
UPDATE:我引入封装子对象的ChildViewModel
的原因之一是验证需求域模型对象应始终有效(例如,孩子的名字不得包含数字)。但是,文本框应显示无效值。在这个非常简单的示例中,ChildrenView
由一个列出ChildViewModels
的数据网格组成。用户可以在DataGrid“name”列中看到无效名称,但子对象始终有效
ChildrenView
是一个用户控件:
<views:ChildrenView ChildrenAware="{Binding SelectedItem.ChildrenAware, Mode=OneWay}"/>
我的目标:我想测试ObservableCollection(带有类型参数ChildViewModel
)是否填充了(模拟的)ChildViewModel
对象
问题:执行无参数构造函数的原因是我无法使用构造函数注入(并注入可以创建ChildViewModel
s的组件)
问题:我可以看到两种解决方案:使用属性注入或StaticClass
,它具有类型为IViewModelFactory
的set/get属性,我可以模拟:
var mockFactory = new Mock<IViewModelFactory>();
mockFactory.Setup(m => m.CreateChildViewModel(mockChild.Object))
.Returns(mockChildViewModel);
StaticClass.ViewModelFactory = mockFactory.Object;
var mockFactory=new Mock();
mockFactory.Setup(m=>m.CreateChildViewModel(mockChild.Object))
.返回(mockChildViewModel);
StaticClass.ViewModelFactory=mockFactory.Object;
还有其他的吗?我应该选择哪一个
问题:无参数构造函数被执行,为什么我不能使用
构造函数注入(并注入可以创建
ChildViewModels)
也许我没有完全理解你的问题。你为什么不呢
如果您的ViewModel
如下
public class ChildrenViewModel
{
public ChildrenViewModel()
{}
public ChildrenViewModel(IViewModelFactory<IChildViewModel> factory)
{
ChildViewModels = new ObservableCollection<IChildViewModel>(factory.Create());
}
public ObservableCollection<IChildViewModel> ChildViewModels { get; set; }
}
公共类ChildrenViewModel
{
公共儿童视图模型()
{}
公共儿童视图模型(IViewModelFactory工厂)
{
ChildViewModels=新的ObservableCollection(factory.Create());
}
公共ObservableCollection ChildViewModels{get;set;}
}
然后可以进行虚拟试验
[TestMethod]
public void ChildViewModelsCreatedTest()
{
var factory = new Mock<IViewModelFactory<IChildViewModel>>();
factory.Setup(f => f.Create())
.Returns(new List<IChildViewModel>() { new ChildViewModel() });
var vm = new ChildrenViewModel(factory.Object);
Assert.IsNotNull(vm.ChildViewModels);
Assert.IsTrue(vm.ChildViewModels.Count == 1);
}
[TestMethod]
public void ChildViewModelsCreatedTest()
{
var factory=new Mock();
factory.Setup(f=>f.Create())
.Returns(new List(){new ChildViewModel()});
var vm=新的ChildrenViewModel(factory.Object);
Assert.IsNotNull(vm.ChildViewModels);
Assert.IsTrue(vm.ChildViewModels.Count==1);
}
您可以发布完整的单元测试吗?很难猜出您想要测试什么,因为您没有为您的用户控件创建ViewModels。这是一种代码气味,会导致心碎和失眠。考虑一下--TextBox是否有TextBoxViewModel?否。您将VM绑定到文本框的公共属性。UserControls应该以同样的方式设计。@Will:add作为答案,它值得投票。另外,这样它将是可搜索的,并且更有用。@lll:我想测试ObservableCollection(带有类型参数ChildViewModel)是否正确填充(不执行ChildViewModel代码)。@SunnyMilenov这只是一个旁注,而不是这个OP的问题。对于OP因为使用UC虚拟机而陷入僵局的问题,我有很多答案。
[TestMethod]
public void ChildViewModelsCreatedTest()
{
var factory = new Mock<IViewModelFactory<IChildViewModel>>();
factory.Setup(f => f.Create())
.Returns(new List<IChildViewModel>() { new ChildViewModel() });
var vm = new ChildrenViewModel(factory.Object);
Assert.IsNotNull(vm.ChildViewModels);
Assert.IsTrue(vm.ChildViewModels.Count == 1);
}