如何模拟不是动作参数的viewmodel?

时间:2014-04-22 11:38:21

标签: c# unit-testing asp.net-mvc-4 moq viewmodel

以下是我的行动代码: -

   public ActionResult Edit(int id)
   {        
       ProductViewModel viewmodel = GetProduct(id);

       if (viewmodel != null)
       {
               ....................
       }
    }

在上面的代码中,if条件基于viewmodel.Which从GetProduct()方法返回。其中GetProduct()方法是控制器的私有方法。

我想用MOQ模拟我的单元测试方法中的 ProductViewModel 。任何人都建议我最好的方法是什么?

4 个答案:

答案 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模拟业务逻辑,以便可以单独测试控制器。

最后,这只是另一个很好的例子,它展示了如何对特定代码组件进行单元测试变得困难,它通常指向设计缺陷而不是单元测试/模拟框架无法实现。