我正在阅读 Clean Code: A Handbook of Agile Software Craftsmanship
其中一个例子涉及 Portfolio
类和一个TokyoStockExchange
类(class)。然而,Portfolio
不是很容易测试,因为它取决于 TokyoStockExchange
作为确定投资组合值(value)的外部 API,这样的查找非常不稳定,不利于测试。
因此,他们通过创建一个通用的 StockExchange
来解决这个问题界面并有TokyoStockExchange
和 DummyStockExchange
两者都实现了基类。因此,实现了依赖倒置原则,并且在 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/