2

How can I mock the creation of ChildViewModels 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 (e.g. 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 ChildViewModels).

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?

6
  • Can you post your complete unit tests? It's hard to guess what you are trying to test Commented Feb 25, 2015 at 16:43
  • 3
    You don't, because you don't create ViewModels for your UserControls. This is a code smell, and results in heartbreak and loss of sleep. Think about this--does a TextBox have a TextBoxViewModel? No. You bind your VM to the public properties of the TextBox. UserControls should be designed the same way. Commented Feb 25, 2015 at 16:45
  • @Will: add as answer, it deserves upvoting. Also, that way it'll be searchable, and more useful. Commented Feb 25, 2015 at 23:58
  • @lll: I want to test that the ObservableCollection (with type argument ChildViewModel) is filled up correctly (without executing ChildViewModel code). Commented Feb 26, 2015 at 8:26
  • @SunnyMilenov that's a side note, and not what this OP has an issue with. I've got a number of answers on questions where the OP is at an impasse because they are using a UC VM. Commented Feb 26, 2015 at 14:43

1 Answer 1

1

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); } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.