I have this:
class FooGenerator:IFooGenerator {
private object _generated;
public void Generate() {
// Generating
GenerateSmallPart();
GenerateOtherSmallPart();
GenerateTinyPart();
// A lot similar
}
private void GenerateSmallPart() {
//add small part to _generated
}
private void GenerateOtherSmallPart() {
//add small part to _generated
}
private void GenerateTinyPart() {
//add small part to _generated
}
}
internal interface IFooGenerator {
void Generate();
}
In my application I use only IFooGenerator
via IoC but I want to test all those sub methods.
As I found here, one option is to extract class with all sub methods. But why do i need to do that. It is only being used in FooGenerator
.
Do you have any suggestions how can i make my class more testable?
One of the keys to writing highly testable code is to ensure that there is a strong separation between the different parts of an application, with clear, simple APIs for interaction between those parts.
Testable code is code of high quality. It's cohesive and loosely coupled. It's well encapsulated and in charge of its own state. In short, it's singularly defined in its own proper place so that it's straightforward to maintain and extend.
I will share with you how I usually handle this situation. If I see that I want to test some private methods for some reason (like it is hard to stub input parameters to test all code flows) - this usually means for me that complexity of my class is high and I need to refactor my code. In your case (I have no idea what your methods are doing) you can use something like:
interface IPartGenerator
{
void GeneratePart();
}
class SmallPartGenerator : IPartGenerator
{
void GeneratePart();
}
class OtherSmallPartGenerator : IPartGenerator
{
void GeneratePart();
}
class TinyPartGenerator : IPartGenerator
{
void GeneratePart();
}
class FooGenerator:IFooGenerator
{
private IPartGenerator[] partGenerators = new IPartGenerator[]
{
new SmallPartGenerator(),
new OtherSmallPartGenerator(),
new TinyPartGenerator ()
}
public void Generate()
{
foreach (var partGenerator in partGenerators)
{
partGenerator.GeneratePart();
}
}
}
Now you can test each of the part generators separately.
Who is the client?
Many people (Roy Osherove, Michael Feathers) consider the test client just as valid as the interface or service client.
With that in mind I think it's fine to slightly go against the principle of encapsulation by opening up testable seams by making some private methods public.
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