【问题标题】:MS Test for Void Methods无效方法的 MS 测试
【发布时间】:2013-08-01 12:09:35
【问题描述】:

我有一个 void 方法,我需要对它进行单元测试,有人可以帮我怎么做吗

[TestMethod()]
public void ProcessProductFeedTest()
{
    // TODO: Initialize to an appropriate value
    ProductDataServiceProvider target = new ProductDataServiceProvider();

    target.ProcessProductFeed();
    Assert.Inconclusive("A method that does not return a value cannot be verified.");
}

在上面的代码中,ProcessProductFeed() 是一个 void 方法,它从 SQL Server DB 中获取一些数据并发布到 TIBCO,我该如何为它编写一个单元测试用例

【问题讨论】:

    标签: c# sql unit-testing mstest


    【解决方案1】:

    嗯,你应该测试一下数据是否发布到 TIBCO,基本上。

    对于任何方法,如果主要目的是计算某些东西,您的测试应该测试返回的值是否正确,或者如果这是该方法的主要目的,则应该测试是否发生了适当的副作用。 (当然,您也可以测试错误条件。)

    在不了解 TIBCO 或您的架构的情况下,我无法真正评论您如何测试发布部分。我个人会将阅读、处理和发布这三个阶段分开 - 然后每个部分都可以独立于其他部分进行测试。

    【讨论】:

    • 应强调单独测试每个组件。一次性测试整个事情在恕我直言是非常危险的,因为这意味着业务中的逻辑错误可以被其他层掩盖。
    • 一起测试所有组件将是集成测试而不是单元测试。
    • @Romoku 我知道,但人们经常忘记这一点并做类似testing moq 之类的事情
    【解决方案2】:

    从您的班级中抽象出持久性和 TIBCO 通信。例如。您可以使用一些存储库接口与 SQL 服务器进行通信:

    public interface IProductsRepository
    {
        IEnumerable<Product> GetSomeProducts();
        // other members
    }
    

    还有一些与 TIBCO 通信的网关(我将其命名为 Stock,但您应该提供业务特定名称):

    public interface IStockGateway
    {
        void DoSomethingWithProducts(IEnumerable<Product> products);
        // other members
    }
    

    然后让你的类依赖这些抽象。您将能够模拟它们并验证类行为:

    public class ProductDataServiceProvider
    {
         private IProductsRepository _productRepository;
         private IStockGateway _stockGateway;
    
         // inject implementations
         public ProductDataServiceProvider(
             IProductRepository productRepository,
             IStockGateway stockGateway)
         {
             _productRepository = productRepository;
             _stockGateway = stockGateway; 
         }
    
         public void ProcessProductFeed()
         {
              // use repository and gateway
         }
    }
    

    现在,回到测试。您的提供商的职责是什么 - 从产品存储库中获取一些产品(此存储库的实现将从 SQL 数据库加载产品)并将它们传递给网关(网关的实现会将产品发布到 TIBCO)。这是使用Moq 库的测试:

    [TestMethod]
    public void ShouldPassSomeProjectToStock()
    {
        // Arrange
        var products = new List<Product>() { }; // create some products
        var mockRepository = new Mock<IProductRepository>();
        mockRepository.Setup(r => r.GetSomeProducts()).Returns(products);
    
        var mockGateway = new Mock<IStockGateway>();
        mockGateway.Setup(g => g.DoSomethingWithProducts(products));
    
        var provider = new ProductDataServiceProvider(mockRepository.Object, 
                                                      ockGateway.Object);
        // Act
        provider.ProcessProductFeed();
        // Assert
        mockRepository.VerifyAll(); // verify products retrieved from repository
        mockGateway.VerifyAll(); // verify products passed to gateway
    }
    

    【讨论】:

    • @CSharped 谢谢 :) 还有一件事 - 有两种类型的测试 - 基于状态的测试,它在运行后验证系统的状态(即公共属性,返回的结果),以及基于交互测试,它验证您的对象如何与其依赖项进行通信。我建议您阅读 Fowler 的文章 Mocks Aren't Stubs 以更好地了解这些不同的方法
    • @CSharped 还请记住,测试应该是FIRST,这意味着您在单元测试提供者时不应该使用真实的数据库或 TIBCO
    猜你喜欢
    • 2010-09-19
    • 2021-08-06
    • 2016-08-14
    • 1970-01-01
    • 2017-01-10
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多