我有一个类(为简单起见,我称之为MyCustomCommand),它基本上接受两个Execute和CanExecute的Delegates。该类实现ICommand。然后,这允许我在我的视图模型中声明一个属性,我将其绑定到XAML。
问题是我遇到了一个场景,我需要模拟视图模型,因为我的一个命令名为ApplyChangesCommand。我不相信依赖是一件坏事。在这一点上它是相对必要的。
由于这种依赖性,我正在使用模拟设置创建一个Callback,它基本上“无所事事”来规避依赖。
现在我已经模拟了视图模型,任何实例属性当然都是null。这包括我的命令。
简单的例子是:
private void _somethingToExecute;
public ICommand ApplyChangesCommand { get { return MyCustomCommand(_somethingToExecute, e=>true); }
Mock有什么方法可以实际调用ApplyChangesCommand的_somethingToExecute吗? Callbase没有削减它,我想不出任何其他方式来做它。
一种解决方法是将“_somethingToExecute”公开并在我的测试中创建ApplyChangesCommand,但我不是粉丝。
任何建议表示赞赏。
由于
答案 0 :(得分:1)
好的,既然我已经有更多的时间来看待这个没有匆忙上班,我就看到了这个问题。你应该做的是使用注入工厂来创建ApplyChangesCommand
。然后,对于VM的单元测试,您只需验证该命令是否返回工厂创建的命令。以下是一个例子:
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);
}
}
}
这假设您每次调用get时都想要创建一个新命令(这似乎是您设置它的方式)。如果您只需要为VM的生命周期创建一个命令,显然您只需通过VM构造函数中的工厂创建命令。
要对此进行单元测试,您可以执行以下操作:
[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));
}
(对于你的代表实际是什么,改变Action
。)
这是您应该对VM的命令进行单元测试的全部内容。如果您想测试行为是您所期望的(意味着,它执行传入的委托并使用该委托返回预期值),那么这就是验收测试的领域。
注意:我在测试示例中使用了Moq模拟框架语法。
就个人而言,我不会将这样的代表传递给Command
。我会注入Command
所需的任何内容,并在Command
内部拥有所有逻辑,在那里更容易进行单元测试,并且对VM有更宽松的依赖性。