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?
To test an application it is not enough to use unit tests. You must also perform functional testing and regression testing. Database access falls outside the scope of unit testing, so you would not write unit tests that include database access.
Mocking and stubbing are the cornerstones of having quick and simple unit tests. Mocks are useful if you have a dependency on an external system, file reading takes too long, the database connection is unreliable, or if you don't want to send an email after every test.
Unit tests should never connect to a database. By definition, they should test a single unit of code each (a method) in total isolation from the rest of your system.
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. ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With