如何编写moq测试来设置返回计数值的方法

时间:2015-04-01 11:11:39

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

在我的控制器操作中,每当添加新产品时,我都会检查数据库中是否已存在此产品。此检查的代码类似于

 public ActionResult Index(ProductModel model)
    {
      var productCount = _productsService.GetAll(true).Count(x => x.ProductNumber == model.ProductNumber);

      if (productCount > 0)
          ModelState.AddModelError("ProductNumber", Product already present in the system!");

       // more processing
     }

我是MOQ测试的新手,并尝试编写一个单元测试来设置GetAll方法,该方法将返回0.我写了类似的东西,但它似乎不起作用

 var _productsService = new Mock<IProductsService>();
_productsService.Setup(m => m.GetAll(true).Count()).Returns(0);

有什么想法吗?感谢

2 个答案:

答案 0 :(得分:1)

看一下这篇文章: Expression references a method that does not belong to the mocked object

他基本上有同样的问题,你试图模拟扩展方法Count()

答案 1 :(得分:1)

这不是你使用Moq的方式 - Count很可能不是你的方法(它是LINQ /其他第三方),你不要嘲笑它。你需要模拟的是GetAll方法,这是一个可模拟依赖项的方法。您“告诉”GetAll返回与参数匹配的模型的产品,如下所示:

[Test]
public void Index_ReportsModelError_WhenProductAlreadyExists()
{
    const int ExistingProductNumber = 10;
    var _productsService = new Mock<IProductsService>();
    var existingProduct = new Product { ProductNumber = ExistingProductNumber };
    _productsService.Setup(m => m.GetAll(true)).Returns(new [] { existingProduct });

    controller.Index(new ProductModel { ProductNumber = ExistingProductNumber });

    // Assert
}

修复现有测试非常简单,只需确保GetAll永远不会返回与Index参数中的数字相同的产品:

const int ExistingProductNumber = 10;
const int NewProductNumber = 20;
var _productsService = new Mock<IProductsService>();
var existingProduct = new Product { ProductNumber = ExistingProductNumber };
_productsService.Setup(m => m.GetAll(true)).Returns(new [] { existingProduct });

controller.Index(new ProductModel { ProductNumber = NewProductNumber });

// Assert