How to unit test a service using PetaPoco.Database

I use PetaPoco in my current project as micro ORM, and I have to say that I like it. However, I found myself struggling with a simple script - unit testing services that use 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); } } 

I use IoC (Castle.Windsor) to inject both IMyService and PetaPoco.Database , where necessary.

Now, when I try to run a unit test on my service, I cannot correctly comment on stub PetaPoco.Database to make sure that the Save method was correctly called. I use NUnit and Rhino.Mocks for unit testing and ridicule.

 [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(); } } 

I know that this can be solved if I extract the interface from PetaPoco.Database and mock it or by virtualizing the PetaPoco methods that I want to make fun of, but the fact is that I do not want to make changes to PetaPoco at all.

Is this doable?

+7
source share
2 answers

My branch located here: https://github.com/schotime/PetaPoco already has an interface defined for the Database class.

Also there is my new fork https://github.com/schotime/NPoco or NPoco on nuget, which has the same api.

I would use one of them.;)

+4
source

You are already abstracting the interaction with PetaPoco.Database using IMyService interactions, so why do you need another abstraction? With your current approach, you can check the interaction with the database using IMyService, for example.

 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 } } 

and to test it, you simply mock the interaction using the IMyService layout / stub.

Now, regarding your original solution, if the public methods of PetaPoco are not virtual, I would unlock it, fix the code and send them a transfer request. Otherwise, your approach looks good to me.

+1
source

All Articles