Reputation: 40062
Lets say I have the below method called DoSomething.
When writing unit tests how do I know whether to use a Fake, Mock or Override approach and why is one better than the other?
public List<MyClass> DoSomething()
{
List<MyClass> data = GetData();
if (data.Count == 0)
return new List<MyClass>();
data = GetFormattedData(data);
if (data.Count == 0)
return new List<MyClass>();
return data;
}
[Test]
public void DoSomething_NoData_ReturnsEmptyList()
{
//Change method parameters to pass in IDataProvider that exposes GetData method
//Create FakeProvider class implementing IDataProvider
//Ensure FakeProvider.GetData returns no data
//Create FakeClass that inherits class from DoSomething class
//Make FakeClass.GetData return no data
//When DoSomething is called in the test it will call the parent class
//Create Mock of class that DoSomething/GetData/GetFormattedData is in
//Tell mock to make sure GetData returns empty list
//Call DoSomething in test
}
[Test]
public void DoSomething_NoFormattedData_ReturnsEmptyList()
{
//Same possibilities exist as above
}
Upvotes: 0
Views: 306
Reputation: 1705
In this case you could supply your function with the data so that the function signature would be public List<MyClass> DoSomething(List<MyClass data)
Then your function would only have a single responsibility and that would be to format the data.
If you still want to do the data fetch withing your function and you will be accessing a database or external service I would use dependency injection and mocking to test the function.
Generally it is good to avoid dependencies if possible. It all depends of course, if you don't do any other data fetching in your class then it's just a matter of how far down you will send your dependency.
Upvotes: 1
Reputation: 31464
How exactly is fake approach different from override one? In both cases you'll most likely end up having to create new class inheriting from the one you want to test.
Anyways, I don't see much differences to be honest, and IMO you got two options:
Both are valid and none is way better than the other. Problem with extract and override is that you'll need extra types/files. That of course means more stuff to manage by hand - if that can be avoided, it should be. Personally, I'd go with this one only when existing mocking frameworks can't handle your scenario.
Major advantage of mocking/injection technique is that it forces you to do better design - having SOLID principles in mind and overral writing more testable/managable code. Not to mention, there're many frameworks supporting this technique (Moq, RhinoMocks, FakeItEasy - to name the most popular ones).
Upvotes: 0