【问题标题】:Is it a test smell to mix in real implementation and mocks?混入实际实现和模拟中是一种测试气味吗?
【发布时间】:2011-03-23 18:19:44
【问题描述】:

我有一个消费者类负责消费一个字符串并决定如何处理它。它可以解析并将解析数据插入数据库或通知管理员。

下面是我的实现。

public void Consume(string email)
{
    if(_emailValidator.IsLocate(email))
    {
        var parsedLocate = _parser.Parse(email);

        // Insert locate in database
    }
    else if(_emailValidator.IsGoodNightCall(email))
    {
        // Notify email notifying them that a locate email requires attention.
        _notifier.Notify();
    }
}

下面是我的单元测试。

// Arrange
var validator = new EmailValidator();
var parser = new Mock<IParser>();
var notifier = new Mock<INotifier>();
var consumer = new LocateConsumer(validator, parser.Object, notifier.Object);
var email = EmailLiterals.Locate;

// Act
consumer.Consume(email);

// Assert
parser.Verify(x => x.Parse(email), Times.Once());

在单元测试中混合模拟和实际实现是否会产生代码异味?另外,如何总是必须测试方法abc() 是否总是运行一次?每次我在 if 块中添加一个函数时添加一个新的单元测试似乎是不对的。好像如果我继续添加到我的 Consume 方法,我会创建一个陷阱。

谢谢。

【问题讨论】:

    标签: c# unit-testing design-patterns dependency-injection


    【解决方案1】:

    为了吹毛求疵,单元测试是独立测试单元的自动化测试。如果将两个或更多单元组合在一起,则不再是单元测试,而是集成测试

    但是,根据您集成的单元类型,进行大量此类集成测试可能还不错。

    Krzysztof Kozmic 最近写了一篇关于此的博客文章,其中他描述了Castle Windsor has very few unit tests 的方法,以及许多集成测试。 AutoFixture 在这些类型的集成测试中也占有很大份额。我认为最重要的一点是,作为一般规则,集成不得跨越库边界

    在任何情况下,您都可以将实际实现视为Test Double Continuum 的一个极端,因此就像在某些场景中使用 Stub、Mocks、Spies 或 Fakes 一样,还有实际实施可能有意义的场景

    但是,请记住,您不再单独测试单元,因此您确实在单元之间引入了耦合,使得独立更改每个单元变得更加困难强>。

    总而言之,我仍然认为它是一种气味,因为它应该始终是一个停下来思考的机会。不过,闻到气味也仅此而已,有时,经过深思熟虑后,您可以决定继续前进。

    【讨论】:

    • +1 或许我们应该发明一个新术语 lightweight integratintestnearly unittest 将库中的几个类组合起来作为可接受的努力-tradeof-smell :-)
    • 是的,这也是我在阅读 Krzysztof 的帖子时的第一个想法,但我还没有想出一个好听的名字。
    • +1 很好的答案。虽然我同意你所说的一切,但我不确定你所说的我是否完全遵循。我同意我的测试引入了模块之间的耦合。在这个测试中没有使用容器来连接我的模块(我不相信这是最好的使用途径)如何避免耦合?这似乎是不可避免的。在应用程序本身中,这不是问题,因为我使用 Windsor 将所有内容连接起来,并在组合根中解析我的主要对象(顺便说一句很棒的文章)。我能想到的唯一解决方案是通过穷人的 DI 在设置方法中连接我的 Consumer 类。
    • 如果我正确理解了这个问题,也许这个答案可能对你有帮助:stackoverflow.com/questions/1465849/using-ioc-for-unittesting/…
    【解决方案2】:

    我会说是的。单元测试应该没有组件之间的依赖关系。

    【讨论】:

      【解决方案3】:
      > Is it a test smell to mix in real implementation and mocks?
      

      这是一个集成测试(组合 2 个或更多模块)而不是单元测试(单独测试一个模块)

      我的回答是:我认为在集成测试中有模拟是可以的。

      【讨论】:

      • +1 但是,我认为答案需要更多详细说明,因此我将自己的想法添加为单独的答案。
      猜你喜欢
      • 2011-06-08
      • 2012-09-12
      • 2022-08-07
      • 2012-04-25
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多