【问题标题】:Writing tests for a pricing method为定价方法编写测试
【发布时间】:2012-01-05 20:55:24
【问题描述】:

我是单元测试/TDD 的新手,在某些方面难以理解。例如,我不确定测试应该如何完成想象以下场景。

我正在编写测试以确保我获得正确的产品价格。一种产品可以有不同的尺寸并以一定数量的数量购买。产品的价格会反映大小和数量。

例如:

产品 A 的定价矩阵如下(数量在侧面,尺寸在顶部)

----------------------------
|     | xs |  s |  m |  l  | 
----------------------------
|  250| 10 | 20 | 50 | 100 | 
----------------------------
|  500| 20 | 40 | 60 | 110 | 
----------------------------
| 1000| 15 | 25 | 55 | 105 | 
----------------------------
| 1500| 12 | 22 | 52 | 102 | 
----------------------------

现在说我正在为类方法编写测试

Pricer.GetPrice(Product p, string size, int quantity)

我应该测试每个产品/尺寸/数量的组合吗?正如你可以想象的那样,这可能意味着大量的测试。

如果价格来自数据存储,因此可能会发生变化,您如何保持测试正确,或者这只是一个令人讨厌的产品?

还有没有人有任何关于编写测试/TDD 的好链接可供阅读。也许会通过 CRUD/Repositories,因为这似乎有点像鸡和蛋类型的场景。

【问题讨论】:

标签: c# unit-testing tdd


【解决方案1】:

听起来您的定价逻辑有两个要素。

  1. 将价格矩阵数据结构(大小、数量截止)对映射到价格。

  2. 采用价格矩阵和Product 实例并返回价格的函数。

测试价格矩阵是没有意义的;数字是任意的。如果你觉得你需要测试这个功能,我会给它传递不同的假的、硬编码的测试矩阵和不同的模拟产品,并测试以验证正确的价格。最相关的边缘情况可能是当您要求准确或与一个分界的截止数量的价格时。

【讨论】:

  • 会接受这个作为答案,尽管所有答案都对我的思路有所帮助,非常感谢。
【解决方案2】:

单元测试是关于测试尽可能小的代码单元,所以在这种情况下,您只关心方法返回预期价格。如果该方法是从外部获取定价数据,那么它会做两件事:获取定价数据和计算价格。您已发现对SRP 的违规行为。

将其分为两种方法:一种是获取定价数据,另一种是计算价格(使用作为参数传递的定价数据)。

所以你的目标方法现在看起来像:

GetPrice(Product p, string size, int quantity, sometype pricingData)

现在您可以单独测试计算:

var pricingData = GetKnownPricingData(); // get a set of dummy pricing data
var result = Pricer.GetPrice(product, size, quantity, pricingData);

然后您可以根据已知的定价数据检查预期的结果。

【讨论】:

  • 感谢 Igby 帮助澄清了我的想法。
  • 您希望尽可能多地分离关注点,而不会达到收益递减点。有可能过度应用良好设计的原则,最终导致架构复杂化并抹去您寻求的好处。如果从定价器外部注入定价数据感觉更整洁且不会过于晦涩,那就去做吧。这当然是一种常见的设计模式。但请始终权衡收益与成本,并牢记YAGNI
【解决方案3】:

我认为您的测试需要具体,并且您需要在开始编写测试之前确定要测试的内容。

考虑添加两个数字?您不必测试要添加的 2 个数字的每个给定组合。您编写一个测试并给它 2 个数字并检查返回的值是否确实是这些数字的总和。

您询问了有关测试每种尺寸/数量组合的问题。如果没有定义的计算来确定这一点,并且你有用于计算的变量值,你就不能真正测试它。

您可以对此进行测试:X 的大小和 Y 的数量应该给出 Z 的价格。插入 X 和 Y 的值并确保您获得 Z 的预期值。

如果 X 或 Y 没有值怎么办?你失败了吗?返回 0?这些东西你可以测试。

【讨论】:

    【解决方案4】:

    在现实生活中,您通常会存根数据库,因此它将返回已知对象,而与存储无关。如果您正在使用例如。用于测试的 NUnit 框架,您也可以使用 TestCaseAttribute 装饰您的测试,以运行具有许多不同参数和返回值的测试。

    【讨论】:

      猜你喜欢
      • 2016-03-24
      • 2018-08-17
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多