if (!string.IsNullOrEmpty(JsonResult)) { var APIResult = JsonConvert.DeserializeObject<List<PTXBusRouteResult>>(JsonResult);
if (APIResult != null && APIResult.Count > 0) { var Route = APIResult.First(); Result = new BusRouteDTO { Name = Route.RouteName.Zh_tw, BusStops = new List<BusRouteDTO.BusStop>() };
foreach (var stop in Route.Stops) { Result.BusStops.Add(new BusRouteDTO.BusStop { ID = stop.StopUID, Name = stop.StopName.Zh_tw }); } } }
return Result; } }
修改Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classProgram { staticvoidMain(string[] args) { //new PTX時變成要帶入呼叫API的實體 var PTXFunction = new PTX(new MyRestSharp());
[TestClass()] publicclassPTXTests { [TestMethod()] publicvoid GetTest_傳入縣市和公車路線名稱_如果查的到資料_應回傳該路線的BusRouteDTO() { //arrange var RestSharpMock = new MyRestSharpMock(); var Sut = new PTX(RestSharpMock); //注入我們模擬的假物件MyRestSharpMock var City = "Taipei"; var RouteName = "307";
var expected = "307"; //act var actual = Sut.Get(City, RouteName);
如果今天上線後發現錯誤,而發生錯誤的地方是在呼叫API的程式,那該修改的是誰?當然是MyRestSharp.cs,也絕對不是PTX這支程式,因為它職責掌管的邏輯全部都是正確的。而我們現在單元測試以及MyRestSharpMock都是在做什麼? 都是在輔助我們驗證PTX所有包含到的邏輯,我們並不關注外部其他程式到底幹了什麼,退一萬步說(好啦其實退一步就可以了)(你好煩)今天IRestSharp這個Interface你的夥伴忘記去實作導致程式上線壞了,那也不會是改你的PTX吧,要改可以,over my dead body先,所以希望這囉說的補充可以幫助釐清這件事情。
[TestClass()] publicclassPTXTests { [TestMethod()] publicvoid GetTest_傳入縣市和公車路線名稱_如果查的到資料_應回傳該路線的BusRouteDTO() { //arrange //透過NSubstitute跟它說你想Mock實作的Interface var NsubRestSharpMock = Substitute.For<IRestSharp>(); var Sut = new PTX(NsubRestSharpMock); //注入
//期望API回傳的Json var sb = new System.Text.StringBuilder(12766); sb.AppendLine(@"[{""RouteUID"":""TPE16111"",""RouteID"":""16111"",""RouteName"":...後略");
//這邊的意思是,當這個透過NSubstitute Mock的物件 //被呼叫Get的方法時,且帶入的參數是我們這邊寫的字串 //就回傳Returns那裡面我們設定的字串 NsubRestSharpMock.Get("http://ptx.transportdata.tw/MOTC/v2/Bus/StopOfRoute/City/Taipei/307?%24top=1&%24format=JSON") .Returns(sb.ToString()); var City = "Taipei"; var RouteName = "307";
var expected = "307"; //act var actual = Sut.Get(City, RouteName);