since i do not get my head around the unit tests.
I have a service
public interface IMyService
{
public List<Person> GetRandomPeople();
}
And then in my MVC Project I have the implementation of this service
public MyService : IMyService
{
public List<Person> GetRandomPeople();
{
...the actual logic the get the People here. This is what i want to test ?
}
}
Then in my controller
public HomeController : Controller
{
IMyService _myService;
public HomeController(IMyService myService)
{
_myService = myService
}
}
Then in the Action Method I will use
public ActionResult CreateRandom()
{
List<Person> people = _myService.GetRandomPeople();
return View(people)
}
Note : The person repo is in my service, just typed this out quickly, so i have a repo.
My Question : How would i test my Service implementation in my Tests projects. I am really stuck now, and i think this is going to the “light goes on” moment in my TDD future.
thanks in advance.
The point of injecting the service interface into the controller is to allow you to test the controller in isolation. To test that, you pass in a mock or fake IMyService.
Depending on how your service is implemented, you may need to test your service with integration tests. Those should be separate from your unit tests (as you don’t want to run them continuously).
For example, let’s say IMyService is implemented with Entity Framework. You need to actually run the LINQ to Entities against a database to test it. You could use a local database, you could have EF create and populate a database on the fly, etc. Those aren’t unit tests (they use I/O), but they’re still important.
Other persistence frameworks may permit you to test against in-memory data sets. That’s fine; I’d still consider that an integration test (your code + the framework) and would separate it from your unit tests.
The trick is to keep the business logic out of the service implementation. Restrict that (as much as possible) to pure data-access code. You want to test your business logic with unit tests.
EDIT:
To address the question in the comment (“when you need to create stubs”):
You create stubs, fakes, test doubles, or mocks (there’s a lot of terminology) when you have a class that you want to test in isolation (the system under test, or SUT) and that class has injected dependencies.
Those dependencies are going to be abstract in some way – interfaces, abstract classes, classes with virtual methods, delegates, etc.
Your production code will pass concrete implementations in (classes that hit the database, for instance). Your test code will pass test implementations in.
You could pass a simple stub implementation (just write a dummy class in your test project that implements the interface and returns fixed values for its members), or you could have a fancier implementation that will detect what calls are made and what arguments are passed (a mock object). You can write all of this by hand. It gets tedious, so many testers use mock object frameworks (also known as isolation frameworks). There are many of these (often several for any given language); I tend to use either NSubstitute or Moq in .NET.
Learning to write tests takes time. It helped me a lot to read several books on the subject. Blog posts may not give enough background. There are some excellent suggestions in the (sadly closed) question here.
The short answer is that you create stubs or mocks when your tests require them.