How to Unit-Test CRUD Operations on a Repository Correctly

c# crud entity-framework repository unit-testing

Question

I understand that this may seem like a wide inquiry, so allow me to elaborate. I have a Repository with two concrete implementations—a MockRepository and a EntityFrameworkRepository—exposed through an interface.

I now have a Unit-Test project that allows all tests to be performed against the either repository by just moving a line in the code.[TestInitialize] .

Basically, I'm asking "How should I write the tests?"

What I have is this:

34 zzzz create

// Arrange.
var foo = new Foo { .. };

// Act
Repository.Add(foo);
UnitOfWork.Commit();

// Assert
Assert.IsTrue(foo.Id > 0);

44-34-5 etrieve

// Arrange.
var fooToGet = 1;

// Act
var foo = Repository.FindSingle(fooToGet);

// Assert
Assert.IsNotNull(foo);
Assert.AreEqual(foo.Id, fooToGet);

pdate zzz-52 pdate

// Arrange.
var fooToGet = 1;
var nameToChangeFooTo = "FooBar";

// Act
var foo = Repository.FindSingle(fooToGet);
foo.Name = nameToChangeFooTo;
UnitOfWork.Commit();
var fooRetrievedAgain = Repository.FindSingle(fooToGet);

// Assert
Assert.IsNotNull(foo);
Assert.AreEqual(fooRetrievedAgain.Id, fooToGet);
Assert.AreEqual(fooRetrievedAgain.Name, nameToChangeFooTo);

elete zzz-61 elete

// Arrange.
var fooToGet = 1;

// Act
var foo = Repository.FindSingle(fooToGet);
Repository.Remove(foo);
UnitOfWork.Commit();
var fooRetrievedAgain = Repository.FindSingle(fooToGet);

// Assert
Assert.IsNull(fooRetrievedAgain);

For the Mock and EF repositories, it works ok, but my primary issue is C (Create). On my repository, I'm not sure how to test an add operation. It makes no difference what I'm doing.

It passes for the EF Repository, but I have to use reflection to change the ID in the in-memory collection in order for it to pass for my mock repository (nasty).

So, could you kindly provide some guidance on how to test CRUD operations on the Repository Pattern in the right way?

This application uses Unit of Work/Repository Patterns,.NET 4, C#, Entity Framework 4, and ASP.NET MVC.

Thanks.

EDIT

Just to be clear, guys: these are not the unit-tests that I currently have. I have business-rule tests and unit tests for my service layer.

If my aforementioned Repository tests fail, both of the latter will (and ought to) fail. To unit-test the simple operations of my Repositories, is what this is all about. Am I mistaken?

1
9
10/22/2010 4:12:16 AM

Accepted Answer

One option is to test the behavior of your mappings, queries, and repositories using an in-memory DB like SqlLite. Ayende here discusses this and provides an example using NHibernate.

Utilizing test fakes is another option that seems to answer your immediate worry of establishing the Ids of the domain objects. RhysC here discusses this in this video.

3
10/22/2010 4:14:28 AM

Popular Answer

I believe that your create test should:

  • the repository with a new object
  • declare that an ID was given to it
  • Using the ID, get the inserted object
  • Verify that the read entity's properties match those of the original entity by comparing the two.

The key difference between my unit tests and yours is that I compare object instances using a deep comparison mechanism. My U exams, for instance, appear as follows:

  • the repository with a new object
  • Using the ID, get the inserted object
  • alter a few entity characteristics
  • the repository entity should be updated.
  • using the ID, get the updated object
  • Make that the attributes of the read entity and the updated entity are same by comparing the two (you can define a specific logic for properties that are not updatable)


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow