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

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

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

    發表于:2013-06-18來源:外刊IT評論作者:不詳點擊數: 標簽:tdd
    14. return null; 15. } 16. 17. public IEnumerable GetProducts() 18. { 19. throw new NotImplementedException(); 20. } 21.} 在第一種方法里,我們寫了兩個不同的IProductRepository模擬方法

      14. return null;

      15. }

      16.

      17. public IEnumerable GetProducts()

      18. {

      19. throw new NotImplementedException();

      20. }

      21.}

      在第一種方法里,我們寫了兩個不同的IProductRepository模擬方法,而在第二種方法里,我們的邏輯變得有些復雜。如果我們在這些邏輯中犯了錯,那我們的測試就沒法得到正確的結果,這又為我們的調試增加了額外的負擔,我們需要找到是業務代碼出來錯還是測試代碼不正確。

      你也許還會質疑這些模擬代碼中的這個沒有任何用處的 GetProducts()方法,它是干什么的?因為IProductRepository接口里有這個方法,我們不得不加入這個方法以讓程序能編譯通過——盡管在我們的測試中這個方法根本不是我們考慮到對象。

      使用這樣的測試方法,我們不得不寫出大量的臨時模擬類,這無疑會讓我們在維護時愈加頭痛。這種時候,使用一個模擬框架,比如JustMock,將會節省我們大量的工作。

      讓我們重新看一下之前的這個測試例子,這次我們將使用一個模擬框架:

      01.[TestMethod]

      02.public void GetProductWithValidIDReturnsProduct()

      03.{

      04. // Arrange

      05. IProductRepository productRepository = Mock.Create();

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

      07. ProductService productService = new ProductService(productRepository);

      08.

      09. // Act

      10. Product product = productService.GetByID("spr-product");

      11.

      12. // Assert

      13. Assert.IsNotNull(product);

      14.}

      15.

      16.[TestMethod]

      17.public void GetProductWithInValidIDThrowsException()

      18.{

      19. // Arrange

      20. IProductRepository productRepository = Mock.Create();

      21. ProductService productService = new ProductService(productRepository);

      22.

      23. // Act & Assert

      24. Assert.Throws(() => productService.GetByID("invalid-id"));

      25.}

      有沒有注意到我們寫的代碼的減少量?在這個例子中代碼量減少49%,更準確的說,使用模擬框架測試時代碼是28行,而沒有使用時是57行。我們還看到了整個測試方法變得可讀性更強了!

      2、測試代碼組織的太松散

      模擬框架讓我們在模擬測試中的生成某個依賴類的工作變得非常簡單,但有時候太輕易實現也容易產生壞處。為了說明這個觀點,請觀察下面兩個單元測試,看看那一個容易理解。這兩個測試程序是測試一個相同的功能:

      Test #1

      01.TestMethod]

      02.public void InitializeWithValidProductIDReturnsView()

      03.{

      04. // Arrange

      05. IProductView productView = Mock.Create();

      06. Mock.Arrange(() => productView.ProductID).Returns("spr-product");

      07.

      08. IProductService productService = Mock.Create();

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

      10.

      11. INavigationService navigationService = Mock.Create();

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

      13.

      14. IBasketService basketService = Mock.Create();

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

      16.

      17. var productPresenter = new ProductPresenter(

      18. productView,

      19. navigationService,

      20. productService,

      21. basketService);

      22.

      23. // Act

      24. productPresenter.Initialize();

      25.

      26. // Assert

      27. Assert.IsNotNull(productView.Product);

      28. Assert.IsTrue(productView.IsInBasket);

      29.}

      Test #2

      01.[TestMethod]

      02.public void InitializeWithValidProductIDReturnsView()

      03.{

      04. // Arrange

      05. var view = Mock.Create();

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

      07.

      08. var mock = new MockProductPresenter(view);

      09.

      10. // Act

      11. mock.Presenter.Initialize();

      12.

      13. // Assert

      14. Assert.IsNotNull(mock.Presenter.View.Product);

      15. Assert.IsTrue(mock.Presenter.View.IsInBasket);

      16.}

      我相信Test #2是更容易理解的,不是嗎?而Test #1的可讀性不那么強的原因就是有太多的創建測試的代碼。在Test #2中,我把復雜的構建測試的邏輯提取到了ProductPresenter類里,從而使測試代碼可讀性更強。

      為了把這個概念說的更清楚,讓我們來看看測試中引用的方法:

      01.public void Initialize()

      02.{

      03. string productID = View.ProductID;

      04. Product product = _productService.GetByID(productID);

    原文轉自: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>