c# – 单元测试和Moq’ing构造函数参数问题

问题背景:

我目前正在尝试对MVC4 WebApi项目进行单元测试.

该项目的结构使用注入到相关控制器的构造函数中的facade类.这一切都是通过Unity实现的,以保持紧密耦合到绝对最小值.

即使认为Unity正在实施,在单元测试中我将产品控制器设置如下:

var repositoryFacade = new RepositoryFacade(new RepositorySelector(new RepositoryGenerator()));

var productController = new ProductController(repositoryFacade)

下面的代码显示了控制器类的’GetProducts’方法:

public ProductController(IRepositoryFacade facade)
    {
        _facade = facade;

        productRepository = _facade.GetProductRepository();
    }

    public List<Product> GetProducts()
    {
        return productRepository.GetProducts();
    }

代码目前位于:

如果我只想测试这个方法被击中的次数,我尝试使用Moq框架将我的UnitTest设置如下:

[TestMethod]
    public void Test_The_GetAllProducts_Method_is_Called()
    {

        var mockRepositoryGenerator = new Mock<IRepositoryGenerator>();

        var mockRepositorySelector = new Mock<IRepositorySelector>(mockRepositoryGenerator.Object);

        var mockFacade = new Mock<IRepositoryFacade>(mockRepositorySelector.Object);

        mockFacade.Setup(x => x.GetProductRepositoryV1().GetProducts());

        var productController = new ProductV1Controller(mockFacade.Object);

        var returnedProducts = productController.GetProducts();

        mockFacade.VerifyAll();
    }

问题:

目前,我在尝试在测试中设置模拟对象的构造函数时遇到错误,如下所示:

Constructor arguments cannot be passed for interface mocks.

我理解这一点,因为我是Moq’ing界面,没有构造函数,但这也是我对单元测试和模拟的学习知识有点裸露的地方.

谁能告诉我如何正确地嘲笑这个测试呢?

最佳答案 您的控制器依赖于存储库.最好将此依赖项显式化:

public ProductController(IProductRepository productRepository)
{
    _productRepository = productRepository;
}

public List<Product> GetProducts()
{
    return _productRepository.GetProducts();
}

测试变得更容易:

ProductV1Controller _productController;
Mock<IProductRepository> _mockRepository;

[TestInitialize]
public void TestInitialize()
{
    _mockRepository = new Mock<IProductRepository>();
    _productController = new ProductV1Controller(_mockRepository.Object);
}

[TestMethod]
public void ShouldLoadAllProducts()
{       
    _mockRepository.Setup(r => r.GetProducts()).Return(SomeProducts);

    var returnedProducts = _productController.GetProducts();

    Assert.Equals(returnedProducts, SomeProducts);
    _mockRepository.VerifyAll();
}
点赞