Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TDD: Static methods, dependency injection, caching, and you!

Tags:

c#

oop

tdd

Hope I can explain this somewhat decently, as it's blowing a fuse in my brain today. I'm learning TDD in C#, so I'm still trying to rewire my brain to fit it.

Let's say I have a User class, that previously had a static method to retrieve a User object (simplified below).

public static User GetUser(string username)
{
   User user = GetUserFromCache(username);
   if(user == null)
   {
       user = GetUserFromDatabase(username);
       StoreObjectInCache(user);
   }
   return user;
}

So I'm trying to rewrite this to use dependency injection so I can fake out the "GetUserFromDatabase" method if it needs to go there. That means I have to make the function not static. Whereas the data access layer would construct the user object from the database, mapping the returned columns to the object properties, a retrieval from cache would return a true-blue User object. However, in a non-static method, I can't just say

this = GetUserFromCache(username);

Because it just doesn't work that way. Though I'm by no means the world expert in how to dance around this with OO, it looks like I'd almost have to grab the User object from cache and write another mapping function that would store the returned User object properties into the new User instance.

What's the solution here? Any OO magic I'm missing? Is the only solution to refactor everything to use factories instead of having the instantiation logic in the object itself? Or have I been staring at this too long and missing something completely obvious?

like image 832
Chris Avatar asked Mar 02 '09 20:03

Chris


People also ask

Does static methods improve performance?

They are faster — Static methods are slightly faster than instance methods because in instance methods, you are also working with an implicit this parameter. Eliminating that parameter gives a slight performance boost in most programming languages.

What is a static dependency?

Static dependency is a horror keyword in unit testing. If it's our own code, then we can change it. If static calls are forced by the external library or NuGet package, then we actually cannot get away from it. It will always be there, and the best thing we can do is avoid it.

Is it a good practice to use static methods in Java?

3.4. Pure functions do not operate on any instance or static variables. Therefore, executing a pure function should also have no side effects. As static methods do not allow overriding and referencing instance variables, they are a great choice for implementing pure functions in Java.

Should we test static methods?

Static methods don't need an instance of the class to be invoked — they can be called on the class itself. Although testing a non-static method (at least one that doesn't call a static method or interact with external dependencies) is straightforward, testing a static method is not an easy task at all.


1 Answers

I don't think you're missing any magic and I think refactoring to remove the persistence code from your business objects and into your persistence layer is the right way to go both from a unit testing and a design perspective. You may want to think about having the cache sit between your business layer and the persistence layer, mediating the retrieval/update of your business objects to simplify things. You should be able to mock/fake your cache and persistence layer if you separate things out this way.

like image 116
tvanfosson Avatar answered Oct 17 '22 15:10

tvanfosson