Dot-Net

如何對使用 PetaPoco.Database 的服務進行單元測試

  • May 28, 2012

我在目前項目中使用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) 在需要的地方注入IMyServicePetaPoco.Database

現在,當我嘗試對我的服務進行單元測試時,我無法正確模擬存根PetaPoco.Database以驗證Save方法是否被正確呼叫。我正在使用NUnitRhino.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 公共方法不是虛擬的,我會分叉它,修復程式碼並向他們發送拉取請求。否則,您的方法對我來說看起來不錯。

引用自:https://stackoverflow.com/questions/10766721