Reputation: 105029
Example
I have a repository class (DAL):
public class MyRepository : IMyRepository
{
public void Delete(int itemId)
{
// creates a concrete EF context class
// deletes the object by calling context.DeleteObject()
}
// other methods
}
I also have a service class (BLL):
public class MyService
{
private IMyRepository localRepository;
public MyService(IMyRepository instance)
{
this.localRepository = instance;
}
public void Delete(int itemId)
{
instance.Delete(itemId);
}
// other methods
}
Creating a unit test for MyRepository would take much more time than implementing it, because I would have to mock Entity Framework context.
But creating a unit test for MyService seems nonsense, because it only calls into Repository. All I could check is to verify if it did actually call repository Delete method.
Question
How would you suggest to unit test these pair of Delete methods. Both? One? None? And what would you test?
Upvotes: 7
Views: 1888
Reputation: 6618
In my opinion you need to test both. Maybe you can do the creation EF context class in a seperate factory that can be tested more easy and mock the context class for the MyRepository tests. That will be more easy and using a factory for creating a context calls seems to be quiet useful for me.
Upvotes: 0
Reputation: 161773
Also, if you had created this code with TDD, you would have had a test. It actually matters whether people can call Delete through your service, so you actually have to test it.
Upvotes: 0
Reputation: 25513
Yes, I would definitely write a unit test for the Service Layer. The reason for this is because, you're not just testing that your implementation works now, but you're also testing that it will continue to work in the future.
This is a vital concept to understand. If someone comes along later on and changes your ServiceLayer, and there's no unit test, how can you verify that the functionality continues to work?
I would also write tests for your DAL, but I would put those in a separate assembly called DataTests or something. The purpose here is to isolate your concerns across assemblies. Unit Tests shouldn't be concerned with your DAL, really.
Upvotes: 1
Reputation: 39480
Create the test for the Service. Currently all it does is to call into the Repository Delete method; however, you shouldn't care about that. What if later something happens and the functionality becomes much more complicated? Don't you want to have unit test code that will assure you that the functionality is still working as expected?
If you're exposing your Delete through your Service, you're expecting it to have an effect. Write a Unit Test to test that effect. Depending on your particular needs, I'd say you might not need to have a test on the Repository Delete, particularly if that functionality is getting exercised as part of your Service Delete functionality, but it really all depends on what level of coverage you're trying for.
Upvotes: 0
Reputation: 13655
Yes, both.
IMyRepository mock = ...;
// create Delete(int) expectation
MyService service = new MyService(mock);
service.Delete(100);
// Verify expectations
Your Delete method right now might only call the Delete method on the repository, but that doesn't mean it always will. You want to have unit tests for this partly to verify it behaves correctly and partly as way of defining your specifications of how the repository is to work.
You also aught to have a test that verifies that the constructor will throw an exception if the repository is null. You might also have other validation to do here in this method such as non-negative ID's, or non-zero id. Maybe that doesn't happen here, make it part of the specifications by creating tests that verify the expected behaviors.
They seem trivial but I can all but guarantee it will change one day and your expectation and specifications may not be verified.
Upvotes: 1