要寫好的Unit Test,要盡可能的避免與一些其他因素的關聯,比方說資料庫、實體路徑、或參考檔案…等。
因此可將實做關聯的部分,截取出介面,用Mock的方式,模擬實做,即可做假的關聯資料。
不實際與環境關聯,成為好的、有信心的Unit Test!
下方為實際測試後,可Work的參考寫法Sample,不太理解寫法的差異?! (Mock可用於驗證,Stub可不驗證,只做假Return?!) 待日後再進一步的研究。
目前測試可執行的寫法如下,使用版本為 Rhino Mocks 3.6:
//Sample1 Idbservice service = MockRepository.GenerateStrictMock<Idbservice>(); //Sample2 Idbservice service = MockRepository.GenerateStub<Idbservice>(); //Sample3 Idbservice service = MockRepository.GenerateMock<Idbservice>(); //Sample4 //(必須於設定完成Stub後,搭配 service.Replay(); 使用!) Idbservice service = new MockRepository().StrictMock<Idbservice>(); //Sample5 //(必須於設定完成Stub後,搭配 service.Replay(); 使用!) Idbservice service = new MockRepository().DynamicMock<Idbservice>();2.宣告完成後,加入要Stub的Method或Attritube … 下方寫法也需搭配上方宣告使用,有其對應。
//Sample 1 service.Stub(s => s.GetMyObjsByID(1)).Return(new Myobj()); //Sample 2 //( 只能搭配 new MockRepository().StrictMock<Idbservice>(); 使用! ) SetupResult.For<MyObj>(service.GetMyObjsByID(1)).Return(new Myobj()); service.Replay();3.最後在需使用Service的Class,傳入我們Mock好的Service.(當然此Class必須操作IdbService)
MyService myservice = new MyService(service);這樣就可以使用我們已經Mock好的service。完全的與原環境關聯乾淨分離,不受其影響! 實際舉一個完整範例,大致程式如下:
//宣告要被Mock的Interface Idbservice service = MockRepository.GenerateStub<Idbservice>(); //加入Stub的Method,與其回傳值。 service.Stub(s => s.GetMyObjsByID(1)).Return(new Myobj()); //使用Mock的Interface進行測試。 MyService myservice = new MyService(service);
加油,做好測試程式,提高系統交付品質保證!
Mock與Stub差異,好文參考 http://www.wretch.cc/blog/kojenchieh/15431659
沒有留言:
張貼留言