3、一次測試太多的項目
看看下面的單元測試,請在不使用“和”這個詞的情況下描述它:
01.[TestMethod]
02.public void ProductPriceTests()
03.{
04. // Arrange
05. var product = new Product()
06. {
07. BasePrice = 10m
08. };
09.
10. // Act
11. decimal basePrice = product.CalculatePrice(CalculationRules.None);
12. decimal discountPrice = product.CalculatePrice(CalculationRules.Discounted);
13. decimal standardPrice = product.CalculatePrice(CalculationRules.Standard);
14.
15. // Assert
16. Assert.AreEqual(10m, basePrice);
17. Assert.AreEqual(11m, discountPrice);
18. Assert.AreEqual(12m, standardPrice);
19.}
我只能這樣描述這個方法:
“測試中計算基價,打折價和標準價是都能否返回正確的值。”
這是一個簡單的方法來判斷你是否一次測試了過多的內容。上面這個測試會有三種情況導致它失敗。如果測試失敗,我們需要去找到那個/哪些出了錯。
理想情況下,每一個方法都應該有它自己的測試,例如:
01.[TestMethod]
02.public void CalculateDiscountedPriceReturnsAmountOf11()
03.{
04. // Arrange
05. var product = new Product()
06. {
07. BasePrice = 10m
08. };
09.
10. // Act
11. decimal discountPrice = product.CalculatePrice(CalculationRules.Discounted);
12.
13. // Assert
14. Assert.AreEqual(11m, discountPrice);
15.}
16.
17.[TestMethod]
18.public void CalculateStandardPriceReturnsAmountOf12()
19.{
20. // Arrange
21. var product = new Product()
22. {
23. BasePrice = 10m
24. };
25.
26. // Act
27. decimal standardPrice = product.CalculatePrice(CalculationRules.Standard);
28.
29. // Assert
30. Assert.AreEqual(12m, standardPrice);
31.}
32.
33.[TestMethod]
34.public void NoDiscountRuleReturnsBasePrice()
35.{
36. // Arrange
37. var product = new Product()
38. {
39. BasePrice = 10m
40. };
41.
42. // Act
43. decimal basePrice = product.CalculatePrice(CalculationRules.None);
44.
45. // Assert
46. Assert.AreEqual(10m, basePrice);
47.}
注意這些非常具有描述性的測試名稱。如果一個項目里有500個測試,其中一個失敗了,你能根據名稱就能知道哪個測試應該為此承擔責任。
這樣我們可能會有更多的方法,但換來的好處是清晰。我在《代碼大全(第2版)》里看到了這句經驗之談:
為方法里的每個IF,And,Or,Case,For,While等條件寫出獨立的測試方法。
驅動測試開發純粹主義者可能會說每個測試里只應該有一個斷言。我想這個原則有時候可以靈活處理,就像下面測試一個對象的屬性值時:
01.public Product Map(ProductDto productDto)
02.{
03. var product = new Product()
04. {
05. ID = productDto.ID,
06. Name = productDto.ProductName,
07. BasePrice = productDto.Price
08. };
09.
10. return product;
11.}
我不認為為每個屬性寫一個獨立的測試方法進行斷言是有必要的。下面是我如何寫這個測試方法的:
01.[TestMethod]
02.public void ProductMapperMapsToExpectedProperties()
03.{
04. // Arrange
05. var mapper = new ProductMapper();
06. var productDto = new ProductDto()
07. {
08. ID = "sp-001",
09. Price = 10m,
10. ProductName = "Super Product"
11. };
12.
13. // Act
14. Product product = mapper.Map(productDto);
15.
16. // Assert
17. Assert.AreEqual(10m, product.BasePrice);
原文轉自:http://www.vaikan.com/top-5-tdd-mistakes/