c# - 对为什么对虚拟对象进行单元测试有用感到困惑

标签 c# unit-testing testing tdd

我正在阅读 Clean Code: A Handbook of Agile Software Craftsmanship其中一个例子涉及 Portfolio类和一个TokyoStockExchange类(class)。然而,Portfolio不是很容易测试,因为它取决于 TokyoStockExchange作为确定投资组合值(value)的外部 API,这样的查找非常不稳定,不利于测试。

因此,他们通过创建一个通用的 StockExchange 来解决这个问题界面并有TokyoStockExchangeDummyStockExchange两者都实现了基类。因此,实现了依赖倒置原则,并且在 PortfolioTest 中第一类可以实例化一个 DummyStockExchange , 固定一个公司的股票价格, 分配 DummyStockExchange将实例添加到投资组合中,并将该公司的一些股票添加到投资组合中,然后断言期望值是否确实是正确的值。这是代码:

public class PortfolioTest
{
    private DummyStockExchange exchange;
    private Portfolio portfolio;

    protected void setUp()
    {
        exchange = new DummyStockExchange();
        exchange.fix("MSFT", 100);
        portfolio = new Portfolio(exchange);
    }

    public void GivenFiveMSFTTotalShouldBe500()
    {
        portfolio.add(5, "MSFT");
        Assert.assertEquals(500, portfolio.value());
    }
}

我的问题很简单,为什么

我们正在尝试测试 TokyoStockExchange类与 Portfolio 协同工作类(class)。显然,如果我们用一种设置股票价格的新方法创建另一个类,然后将这些股票中的五只股票提供给投资组合,那么一切都会奏效。看起来.. 测试没用。我明白 TokyoStockExchange基本上不可能用 Portfolio 来测试因为股票价格不断变化,但我不明白在一个相当无用的测试中替代如何帮助这种情况。

这一切似乎类似于不知道我们的加法器程序是否有效,但唯一可用的数字是随机生成的,所以我们创建了一个虚拟类,它给我们一个 2 并测试 2 + 2 = 4 是否有效。 .嗯,是的,显然这是真的。我们仍然可以破解 TokyoStockExchange并且测试仍然会成功,因为它正在测试另一个类。如果有任何事情,这一切似乎具有欺骗性,并且还会导致不得不编写额外的代码来测试我们知道会起作用的东西。

我认为这是我目前在理解单元测试时遇到的最大问题。我知道我错了,我只是没有看到我猜想的光。希望有人能帮助我。

最佳答案

我们的想法是,您希望在与 TokyoStockExchange 隔离的情况下测试 Portfolio 类中的逻辑。如果您使用 Moq 或 Rhino Mocks 等模拟框架,那么您可以轻松模拟 TokyoStockExchange 的不同输出和行为,并编写单元测试以确保 Portfolio 正确响应。您将为 TokyoStockExchange 类编写单独的单元测试。

这并不是说您不需要在两个类之间进行集成 测试。如果不使用模拟对象,就很难正确验证所有场景。

用这样一个简单的类作为示例很难理解它的值(value),但是给定一个更复杂的类,您需要在“实时”类上难以或不可能安排的情况下验证测试用例,单元测试变得更加重要。

关于c# - 对为什么对虚拟对象进行单元测试有用感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11998967/

相关文章:

c# - EF Core DB First,以及如何避免模型生成时的构造函数覆盖

ios - 测试类包返回 Xcode 10 中的主包,而不是单元测试包

java - 方法中的每个可能分支都应该有一个单独的 junit 吗?

testing - Sonar 中的误报操作到底是什么意思?

wcf - 在 Visual Studio 中测试 WSDL

c# - 确定 JToken 是否为叶

c# - Rx 运算符到不同的序列

c# - Android 版本支持推送通知

java - 如何在 Java 单元测试中模拟接口(interface)?

typescript - 使用 Jest 正确模拟库/方法