• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 測試驅動開發上的五大錯誤(3)

    發表于:2013-06-18來源:外刊IT評論作者:不詳點擊數: 標簽:tdd
    05. 06. if (product != null) 07. { 08. View.Product = product; 09. View.IsInBasket = _basketService.ProductExists(productID); 10. } 11. else 12. { 13. NavigationService.GoTo(/not-found); 14. } 15.} 這個

      05.

      06. if (product != null)

      07. {

      08. View.Product = product;

      09. View.IsInBasket = _basketService.ProductExists(productID);

      10. }

      11. else

      12. {

      13. NavigationService.GoTo("/not-found");

      14. }

      15.}

      這個方法依賴于View, ProductService, BasketService and NavigationService等類,這些類都要模擬或臨時構造出來。當遇到這樣有太多的依賴關系時,這種需要寫出準備代碼的副作用就會顯現出來,正如上面的例子。

      請注意,這還只是個很保守的例子。更多的我看到的是一個類里有模擬一、二十個依賴的情況。

      下面就是我在測試中提取出來的模擬ProductPresenter的MockProductPresenter類:

      01.public class MockProductPresenter

      02.{

      03. public IBasketService BasketService { get; set; }

      04. public IProductService ProductService { get; set; }

      05. public ProductPresenter Presenter { get; private set; }

      06.

      07. public MockProductPresenter(IProductView view)

      08. {

      09. var productService = Mock.Create();

      10. var navigationService = Mock.Create();

      11. var basketService = Mock.Create();

      12.

      13. // Setup for private methods

      14. Mock.Arrange(() => productService.GetByID("spr-product")).Returns(new Product());

      15. Mock.Arrange(() => basketService.ProductExists("spr-product")).Returns(true);

      16. Mock.Arrange(() => navigationService.GoTo("/not-found")).OccursOnce();

      17.

      18. Presenter = new ProductPresenter(

      19. view,

      20. navigationService,

      21. productService,

      22. basketService);

      23. }

      24.}

      因為View.ProductID的屬性值決定著這個方法的邏輯走向,我們向MockProductPresenter類的構造器里傳入了一個模擬的View實例。這種做法保證了當產品ID改變時自動判斷需要模擬的依賴。

      我們也可以用這種方法處理測試過程中的細節動作,就像我們在第二個單元測試里的Initialize方法里處理product==null的情況:

      01.[TestMethod]

      02.public void InitializeWithInvalidProductIDRedirectsToNotFound()

      03.{

      04. // Arrange

      05. var view = Mock.Create();

      06. Mock.Arrange(() => view.ProductID).Returns("invalid-product");

      07.

      08. var mock = new MockProductPresenter(view);

      09.

      10. // Act

      11. mock.Presenter.Initialize();

      12.

      13. // Assert

      14. Mock.Assert(mock.Presenter.NavigationService);

      15.}

      這隱藏了一些ProductPresenter實現上的細節處理,測試方法的可讀性是第一重要的。

      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.

    原文轉自:http://www.aqee.net/top-5-tdd-mistakes/

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>