以下是我的行动代码: -
public ActionResult Edit(int id)
{
ProductViewModel viewmodel = GetProduct(id);
if (viewmodel != null)
{
....................
}
}
在上面的代码中,if条件基于viewmodel.Which从GetProduct()方法返回。其中GetProduct()方法是控制器的私有方法。
我想用MOQ模拟我的单元测试方法中的 ProductViewModel 。任何人都建议我最好的方法是什么?
答案 0 :(得分:3)
理想情况下,您的viewModel应该只包含您的视图将绑定到的公共属性。因此,不应该存在需要模拟viewModel类的场景。 如果可以,请模拟GetProduct方法以返回已设置公共属性的ProductViewModel实例。这样,您的viewModel将返回您希望它为测试用例返回的值。
答案 1 :(得分:0)
通常使用MVVM模式如下:
public class MainViewModel : MyViewModelBase
{
private readonly IDataService _dataService;
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
// ...
}
//..
}
你将有一个看起来像的定位器:
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
// Here you'll register your view models
SimpleIoc.Default.Register<MainViewModel>();
}
//..
}
所以,嘲笑这个相当容易,只需使用DI传入你想传递的任何东西,并将你的方法挂钩到静态数据(通常在设计模式下做得很好),或者返回虚拟方法无论你需要什么。
答案 2 :(得分:0)
正确的方法是间接测试GetProduct方法。根据您从某种存储获取信息的名称,您可以模拟该存储并返回由GetProduct在所需的ViewModel中映射的对象。你不应该模拟你正在测试的同一个类的方法。
答案 3 :(得分:0)
您的控制器与业务逻辑非常紧密耦合,在本例中为GetProduct方法。我建议重新构建您的代码,以便为您的&#34;产品&#34;具体的业务逻辑。产品控制器应该依赖于抽象,即接口,而不是具体的任何东西。
使用任何依赖注入框架(如sring.net,MS unity等)将具体实现(依赖项)注入控制器。
现在使用MOQ模拟业务逻辑,以便可以单独测试控制器。
最后,这只是另一个很好的例子,它展示了如何对特定代码组件进行单元测试变得困难,它通常指向设计缺陷而不是单元测试/模拟框架无法实现。