Search code examples
.netunit-testingmockingrhino-mockspetapoco

How to unit test service that is using PetaPoco.Database


I am using PetaPoco on my current project as a micro ORM and i must say that i like it. However, i found myself struggling with simple scenario - 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 am using IoC (Castle.Windsor) for injection of both IMyService and PetaPoco.Database wherever needed.

Now, when i try to unit test my service i am unable to properly mock stub PetaPoco.Database in order to verify that the Save method was properly invoked. I am using NUnit and Rhino.Mocks for unit testing and mocking.

[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 am aware that this can be solved if i extract an Interface from PetaPoco.Database and do the mocking against it, or by virtualizing PetaPoco's methods that i want to mock, but the point is that i don't want to make changes to PetaPoco at all.

Is this doable?


Solution

  • 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 these. ;)