Dot-Net
如何對使用 PetaPoco.Database 的服務進行單元測試
我在目前項目中使用PetaPoco作為微型 ORM,我必須說我喜歡它。然而,我發現自己在簡單的場景中苦苦掙扎——使用PetaPoco.Database的單元測試服務
public class MyService : IMyService { private readonly PetaPoco.Database _database; public MyService(PetaPoco.Database database) { _database = database; } public void SaveSomething(MyObject myObject) { //...custom logic _database.Save(myObject); } }我正在使用IoC (Castle.Windsor) 在需要的地方注入IMyService和PetaPoco.Database。
現在,當我嘗試對我的服務進行單元測試時,我無法正確模擬存根PetaPoco.Database以驗證Save方法是否被正確呼叫。我正在使用NUnit和Rhino.Mocks進行單元測試和模擬。
[TestFixture] public class MyServiceTests { private PetaPoco.Database _database; [SetUp] public void SetUp() { _database = MockRepository.GenerateMock<Database>(""); } [Test] public void ShouldProperlySaveSomething() { //Arrange var myObject = new MyObject(); _database.Expect(db => db.Save(Arg<MyObject>.Is.Anything)); var myService = new MyService(_database); //Act myService.SaveSomething(myObject); //Assert _database.VerifyAllExpectations(); } }我知道如果我從PetaPoco.Database中提取一個介面並對其進行模擬,或者通過虛擬化我想要模擬的 PetaPoco 方法,這可以解決,但關鍵是我不想對PetaPoco進行更改一點也不。
這是可行的嗎?
我的分支位於此處:https ://github.com/schotime/PetaPoco已經為 Database 類定義了一個介面。
還有我的新 Fork https://github.com/schotime/NPoco或 NPoco on nuget 具有相同的 api。
我會使用其中之一。;)
您已經使用 IMyService 互動抽象了與 PetaPoco.Database 的互動,那麼為什麼還需要另一個抽象呢?使用您目前的方法,您應該能夠使用 IMyService 測試與數據庫的互動,例如
public class AuthenticationService { private IMyService myService; public AuthenticationService(IMyService service) { ... } public void Authenticate(string username, string password) { var user = myService.GetUser(username); // <-- Hits the database } }為了測試它,您只需使用 IMyService 的模擬/存根模擬互動。
現在關於您的原始解決方案,如果 PetaPoco 公共方法不是虛擬的,我會分叉它,修復程式碼並向他們發送拉取請求。否則,您的方法對我來說看起來不錯。