我有一个类MainViewModel
,它将几个子视图模型作为依赖项。我想测试MainViewModel
方法。最好的方法是什么?我该如何模仿儿童视图模型?
我的代码如下:
public class MainViewModel:ViewModelBase
{
public MainViewModel(ChildViewModel1 childViewModel1, ChildViewModel2 childViewModel2)
{
this.ChildViewModel1 = childViewModel1;
this.ChildViewModel2 = childViewModel2;
}
public ChildViewModel1 ChildViewModel1 { get; set; }
public ChildViewModel2 ChildViewModel2 { get; set; }
public void MethodThatIWantToTest()
{
this.ChildViewModel1.SomeProperty = "new value";
}
}
public class ChildViewModel1:ViewModelBase
{
private ISomeService someService;
public ChildViewModel1(ISomeService someService)
{
this.someService = someService;
}
public string SomeProperty { get; set;}
}
//Test
public void Should_ChangeChildViewModel1SomeProperty_WhenCallingMethodThatIWantToTest()
{
// arrange
var mainViewModel = new MainViewModel(.., ..); // how to mock here??
// act
mainViewModel.MethodThatIWantToTest();
// assert
Assert.Equal(mainViewModel.ChildViewModel1.SomeProperty, "new value");
}
答案 0 :(得分:2)
怎么样:
public void Should_ChangeChildViewModel1SomeProperty_WhenCallingMethodThatIWantToTest()
{
// arrange -- IService is null because we don't mock
// things that are not being used anyway
var child1 = new ChildViewModel1(null)
// act -- childViewModel2 is null because we don't mock
// things that are not being used anyway
new MainViewModel(child1, null).MethodThatIWantToTest();
// assert -- access child1 directly instead of through the
// property MainViewModel.ChildViewModel1, because this
// makes the test more decoupled (fewer assumptions about
// MainViewModel class). You could however create a test
// checking that the ChildViewModel1 passed to the ctor
// really is returned by the property.
Assert.Equal(child1.SomeProperty, "new value");
}
答案 1 :(得分:1)
依赖性不应该是具体的类,它们应该是抽象。
因此,在您的情况下,您的ChildViewModels
应该实现interface
,而您的MainViewModel
应该依赖于接口。
public interface IChild1
{
string SomeProperty { get; set; }
}
...
public MainViewModel : ViewModelBase
{
public IChild1 ChildViewModel1 { get; set; }
public IChild2 ChildViewModel2 { get; set; }
public MainViewModel(IChild1 child1, IChild2 child2)
{
...
}
...
}
然后,您可以在测试时使用NSubstitute之类的框架将模拟对象注入MainViewModel
。
IChild1 child1 = Substitute.For<IChild1>();
IChild2 child2 = Substitute.For<IChild2>();
MainViewModel vm = new MainViewModel(child1, child2);
答案 2 :(得分:0)
“最佳”方法是不测试子对象并将它们模拟或伪造,然后子对象应该有自己的测试。子对象应该是公共属性作为接口,然后测试应该注入模拟或伪造对象。
假货很有意思,因为你可以存根方法和属性。您必须从界面工作。 http://www.codeproject.com/Articles/680551/Visual-studio-Fakes
Mocking是另一种方式,您可以从子对象类继承为父对象并在测试中进行设置。将对象设置为覆盖并根据需要由被测单元执行。使用模拟或假货来设置快乐和不良测试路径非常容易。