var target = new PickupService(configService, storeSettingService, logger);
var actual = target.GetUpdateStatus(2, new List<string> {"TestWayBillNo"}); actual.Should().BeEquivalentTo(new List<ShippingOrderUpdateEntity> { new ShippingOrderUpdateEntity { AcceptTime = new DateTime(2020, 03, 03, 17, 51, 20), OuterCode = "TestWayBillNo", Status = StatusEnum.Finish } });
Legacy Code 相依 HttpClient
大部份的功能我都可以透過 DI 的手段隔離, 但是之前的 Test Driven Develop 的方法並沒有將 HttpClient 轉換成可以隔離的物件。 另外一部份代碼是透過 Copy Paste 手法產生的代碼,所以也有可能會有 Legacy Code。 這裡我優先處理 HttpClient 。
[email protected]: Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
debug1: Will attempt key: /Users/marsen/.ssh/id_rsa debug1: Will attempt key: /Users/marsen/.ssh/id_dsa debug1: Will attempt key: /Users/marsen/.ssh/id_ecdsa debug1: Will attempt key: /Users/marsen/.ssh/id_ed25519 debug1: Will attempt key: /Users/marsen/.ssh/id_xmss
[Fact] publicvoidCase1_Just_Run() { var target = new PickupService(); long storeId = 0; List<string> waybillNo = new List<string>(); target.GetUpdateStatus(storeId, waybillNo); }
因為沒有想法,所以沒有 Assert 這不算是測試,頂多是一個小工具可以隨時呼叫我的 Production Code 而已
+ var requestContent = JsonSerializer.Serialize(new { Type = "DeliveryOrder", waybillNo }); + var httpContent = new StringContent(requestContent, Encoding.UTF8, "application/json");
前面產生的 TODO 項目並不是「最」重要的, 我應該先處理回傳的資料,讓整件事情串通。 開立 TODO 如下
1 2 3
+ //// TODO Parse Response Entity + //// TODO Switch Status + //// TODO Return ShippingOrderUpdateEntity List
可以得知,我最終會回傳一包 List, 這個時候我可以 Assert 了
修改第一個測試案例
這個階段我開始撥雲見日,我要很明確的寫下第一個測試案例, 第一個案例我會直接作 Happy Case , 也就是目前的呼叫的 API 只打一筆,回傳 Done 的資料。
這裡進一步作需求分析, 呼叫完 API 我會收到一大包 JSON 資料, 需要轉成我可以處理的物件, 其中最重要的欄位 lastStatusId 會回傳各種狀態,
DONE
FAIL
Arrived
Shipping
SMS
Expiry
我只處理
已取貨(DONE) 系統狀態為 Finish
失敗(FAIL、Expiry) 系統狀態為 Abnormal
貨到待取(Arrived) 系統狀態為 Arrived
出貨中(Shipping) 系統狀態為 Processing
分析後,我的測項將會是向 API 循問一筆資料 且回傳一筆為 Done 的 ShippingOrderUpdateEntity 給我。
1 2 3 4 5 6 7 8 9
[Fact] publicvoidCase1_Query_Done_waybillNo() { var target = new PickupService(); long storeId = 1; List<string> waybillNo = new List<string> {"TEST2002181800010"}; var actual = target.GetUpdateStatus(storeId, waybillNo).FirstOrDefault().Status; actual.Should().Be(StatusEnum.Finish); }
var configService = Substitute.For<IConfigService>(); configService.GetAppSetting("pickup.service.url") .Returns("http://www.mocky.io/v2/********"); var target = new PickupService(configService);
在 HttpClient 那邊卡蠻久的,用介面的方法包裝起來也不知道是否合適。 網路上有提供許多不同的作法,單元測試的 TDD 好像趨動不太出來 Production Code 是否需要加入整合測試,甚至是透過呼叫 Production Code 去打 API 作端到端測試,來趨動開發 ? TDD 的 T 是不是不只是 Unit Test 呢 ?