Since following DI and TDD, I'm bit confused as to when should I create a private method. Could you please tell me what should be the rules of thumb to be considered while making a method private keeping testability and Dependency injection in mind?
I believe an example might help here:
Assume I have an interface with 3 methods like the following:
public interface IWordFrequencyAnalyzer
{
int CalculateHighestFrequency(string forText);
int CalculateFrequencyForWord(string text, string word);
IList<IWordFrequency> CalculateMostFrequentNWords(
string text, int n);
}
Now, I can write a class which can implement a private method which takes a string and can compute the frequency of words in it, and later in each public method I can do a manipulation according to it's requirement.In this case I'll be able to test the contract.
OR
I can extract that private method into a seperate class say something like WordProcessor which implements IWordProcessor, with a single public method which splits the sentence into words and pass it as dependency to the implementation of IWordFrequencyAnalyzer. This way the implementation of splitting the words is testable as well.
Which approach will you suggest?
Thanks, -Mike
Since getting more into DI and TDD I ended up using private methods less and less, but the reason was not because I needed them to be public for tests. It's more because, as a by-product of using DI, I'm learning more about applying the SOLID principles to my code and this (in turn) is leading me to write classes with less methods overall and almost none private.
So, let's say you have a piece of your code you're using throughout various methods of your class. You know about DRY and you refactor it out to a private method and all's good. Except that often you realize you can generalize what that private method does and inject that functionality as an external dependency of the class: this way, you can test it and mock it, sure, but above all you can reuse what that method does even in other classes or other projects if needs be. Moving it out of the original class is an application of the single responsibility principle.
As I said this change in the way I code is not directly depending on the fact I use TDD or DI, but it's a by-product of the principles TDD encourages me to enforce and of the convenience that DI containers provide in composing the many small classes that result from this approach.
EDIT: The second approach in the example you added to your question is a good example of what I was talking about. The fact your new WordProcessor class is now testable is a plus, but the fact it's now composable and reusable is the real benefit.
Your methods should be private unless they need to be public for your application, not your test.
Generally you shouldn't make things public just to support unit testing (internal might help there). And in that case, you should generally still be testing public interfaces, not private details of the class, which are much more likely to change and break your test.
If you have access to a copy, Roy Osherove's "The Art Of Unit Testing" addresses this issue pretty well
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