0

I have the following ViewModel

public class MyViewModel : IMyViewModel
{
    private readonly IMyModel myMode;
    private ICommand _myCommand;

    public MyViewModel(IMyModel model)
    {
        _model = model;
    }

    public ICommand MyCommand
    {
        get { return _myCommand ?? (_myCommand = new RelayCommand(x => MyMethod())); }
    }

    private void MyMethod()
    {
        _model.SomeModelMethod();
    }
}

where IMyViewModel is defind as

public interface IMyViewModel
{
    ICommand MyCommand { get; }
} 

and my interface for the model is defined as

public interface IMyModel
{
    void SomeOtherCommand();
} 

Now in my unit test (using NSubstitute) I want to check that when MyCommand is invoked my model receives a call to its method SomeModelMethod. I've tried:

[TestMethod]
public void MyViewModel_OnMyCommand_CallsSomeOtherMethodOnModel()
{
   var model = Substitute.For<IMyModel>();
   var viewModel = Substitute.For<IMyViewModel>();

   viewModel.MyCommand.Execute(null);

   model.Received().SomeOtherMethod();
}

but this doesn't currently work. How do I best test that my Model method is called when a command on my ViewModel is invoked?

James B
  • 8,975
  • 13
  • 45
  • 83
  • Rather than creating a substiture for the viewModel, you're probably going to want to do `new viewModel(model.object)`, or whatever the substitute equivalent is. You don't want to mock the object you're actually testing. – forsvarir Apr 27 '15 at 09:59

1 Answers1

2

Not sure why you're mocking IMyViewModel here. You said you wanted to test whether SomeOtherMethod is invoked when you execute the command in MyViewModel.

You shouldn't be mocking the MyViewModel here.

[TestMethod]
public void MyViewModel_OnMyCommand_CallsSomeOtherMethodOnModel()
{
   var model = Substitute.For<IMyModel>();
   var viewModel = new MyViewModel(model);

   viewModel.MyCommand.Execute(null);

   model.Received().SomeOtherMethod();
}

P.S: I'm not familiar with nsubstitute. But the idea is still same (you shouldn't mock MyViewModel). Make sure you're using the right methods in nsubstitute.

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • Thanks, but Visual Studio is now shouting that is expects a Method, Delegate or Event when trying to invoke `viewModel.MyCommand(null)`. I'm still unclear as how to properly invoke the ICommand. Any suggestions? – James B Apr 27 '15 at 10:09
  • D'oh. It should read `viewModel.MyCommand.Execute(null)` Thanks – James B Apr 27 '15 at 10:11
  • @JamesB Ha, I copied your code and made the same typo :) Glad that you solved it. – Sriram Sakthivel Apr 27 '15 at 11:22