简体   繁体   中英

How can I unit test the view models of a WPF user control

How can I mock the creation of ChildViewModel s in ChildrenViewModel :

IChildViewModel c = new ChildViewModel(child);
children.Add(c);

I'm using ChildViewModel ( there is no ChildView ! ) since a Child (model) class does not implement INotifyPropertyChanged . UPDATE: One of the reasons why I introduced ChildViewModel that encapsulates a Child is a validation requirement. Domain model objects should always be valid (eg the child's name mustn't consist a digit). Nevertheless, the textbox should display invalid values. In this very simple example, ChildrenView consists of a DataGrid that lists the ChildViewModels . The user can see invalid names in the DataGrid "name" column but the child objects are always valid.

ChildrenView is a user control:

<views:ChildrenView ChildrenAware="{Binding SelectedItem.ChildrenAware, Mode=OneWay}"/>

ChildrenViewModel is created in the resources of ChildrenView :

<viewModels:ChildrenViewModel x:Key="ViewModel"/>

My aim : I want to test that the ObservableCollection (with type argument ChildViewModel ) is filled up with (mocked) ChildViewModel objects.

The problem : The parameterless constructor is executed why I can't use constructor injection (and inject a component that can create ChildViewModel s).

The question : I can see two solutions: Using property injection or a StaticClass that has a set/get property of type IViewModelFactory that I can mock:

var mockFactory = new Mock<IViewModelFactory>();
mockFactory.Setup(m => m.CreateChildViewModel(mockChild.Object))
           .Returns(mockChildViewModel);

StaticClass.ViewModelFactory = mockFactory.Object;

Are there any others? Which one should I choose?

The problem: The parameterless constructor is executed why I can't use constructor injection (and inject a component that can create ChildViewModels).

Maybe I'm not understanding your question entirely. Why wouldn't you?

If your ViewModel is like

public class ChildrenViewModel
{
    public ChildrenViewModel()
    {}

    public ChildrenViewModel(IViewModelFactory<IChildViewModel> factory)
    {
        ChildViewModels = new ObservableCollection<IChildViewModel>(factory.Create());
    }

    public ObservableCollection<IChildViewModel> ChildViewModels { get; set; }
}

Then dummy test could be

[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);
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM