Ok, now that I've had more time to look at this not being rushed at work, I see the issue. What you should do is use an injected factory to create the ApplyChangesCommand
. Then for unit testing your VM, you just verify that the command returns the factory created command. Below is an example:
public class MyViewModel
{
private MyCustomCommandFactory _commandFactory;
private void _somethingToExecute;
public MyViewModel(MyCustomCommandFactory commandFactory)
{
_commandFactory = commandFactory;
}
public ICommand ApplyChangesCommand
{
get
{
return _commandFactory.Create(_somethingToExecute, e=>true);
}
}
}
This assumes you're wanting to create a new command every time the get is called (which seems to be how you have it set up). If you want just a single command created for the life of the VM, obviously you can just create the command via the factory in the VM constructor.
To unit test this, you can do something like this:
[Test]
public void ApplyChangesCommand_Always_ReturnsFactoryCreatedCommand
{
Mock<ICommand> mockCreatedCustomCommand = new Mock<ICommand>();
Mock<MyCustomCommandFactory> mockCommandFactory = new Mock<MyCustomCommandFactory>();
mockCreatedCustomCommand.Setup(p => p.Create(It.IsAny<Action>(), e => true))
.Returns(mockCreatedCustomCommand.Object);
Assert.That(systemUnderTest.ApplyChangesCommand, Is.SameAs(mockCreatedCustomCommand.Object));
}
(Change Action
out for whatever your delegate actually is).
This is all you should have to unit test for a VM's command. If you're wanting to test that the behavior is what you expect (meaning, it executes the passed in delegate and returns the expected value using that delegate), then that's the realm of an acceptance tests.
Note: I used the Moq mocking framework syntax in my test example.
Personally, I wouldn't be passing in delegates like that to a Command
. I would instead inject whatever the Command
needs and have all the logic inside the Command
, where it is more easily unit tested in there, and has a looser dependency on the VM.