Realize this may sound like a broad question - so let me clarify. I have a Repository exposed via an interface, with two concrete implementations - a MockRepository and a EntityFrameworkRepository.
Now, i have a Unit-Test project for which all tests can be run against either repository, via flicking over a line in [TestInitialize]
.
My question is basically "How should i write the tests".
Here's what i have:
C reate
// Arrange.
var foo = new Foo { .. };
// Act
Repository.Add(foo);
UnitOfWork.Commit();
// Assert
Assert.IsTrue(foo.Id > 0);
R etrieve
// Arrange.
var fooToGet = 1;
// Act
var foo = Repository.FindSingle(fooToGet);
// Assert
Assert.IsNotNull(foo);
Assert.AreEqual(foo.Id, fooToGet);
U 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);
D 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);
It's working ok, for both the Mock and EF repository, but my main problem is C (Create). I'm not sure how to test an Add operation on my Repository. It doesn't feel right what im doing.
It passes for the EF Repository, but to make it pass in my Mock Repository i had to use reflection to update the ID in the in-memory collection (nasty).
So - can you please share some advice on what are the correct ways to test CRUD operations on the Repository Pattern?
This is an ASP.NET MVC Application, .NET 4, C#, Entity Framework 4 and Unit of Work/Repository Patterns.
Thanks.
EDIT
Just to clarify guys, these are not all the unit-tests i have. I have unit tests for my service layer, as well as business-rule tests.
Both the latter will (and should) fail if my above Repository tests fail. That is the point here, to unit-test the very basic operations of my Repositories. Am i wrong?
If all your application does is CRUD, then there is no point in unit testing it. Now, if there is any kind of business logic manipulating the values as they come out of the db or validating them before them going in, yes, it is a good idea to build unit tests. Testing the CRUD part does not belong in unit testing IMO.
In a modern test management tool, a test repository crops up as you write test cases and keep associating with requirements. It is a live working document that is embedded in your project in a granular way. QA teams can write tests once and easily access them for future use.
You can create a @DataJpaTest and @Autowire your repository into it. For example: @RunWith(SpringRunner. class) @DataJpaTest public class MyJpaTest { @Autowired private ChartRepository chartRepository; @Test public void myTest() { ... } }
One option is to use an in-memory DB like SqlLite to test the behaviour of your mappings, queries and repositories. This is discussed by Ayende here, though his example uses NHibernate.
Another option which seems to address your immediate concern of setting the Ids of the domain objects is to use test fakes. This is discussed by RhysC here.
IMO, your create test should:
I've got many unit tests like yours the main difference is that I'm using a deep comparison method to compare object instances. For instance, my U tests look like this:
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