Unit-testing private methods: Facade pattern - unit-testing

Lots of developers think that testing private methods is a bad idea. However, all examples I've found were based on the idea that private methods are private because calling them could break internal object's state. But that's not only reason to hide methods.
Let's consider Facade pattern. My class users need the 2 public methods. They would be too large. In my example, they need to load some complex structure from the database's BLOB, parse it, fill some temporary COM objects, run user's macro to validate and modify these objects, and serialize modified objects to XML. Quite large functionality for the single metod :-) Most of these actions are required for both public methods. So, I've created about 10 private methods, and 2 public methods do call them. Actually, my private methods should not necessarily be private; they'll not break the internal state of instance. But, when I don't wont to test private methods, I have the following problems:
Publishing them means complexity for users (they have a choice they don't need)
I cannot imagine TDD style for such a large public methods, when you're to write 500+ lines of code just to return something (even not real result).
Data for these methods is retrieved from database, and testing DB-related functionality is much more difficult.
When I'm testing private methods:
I don't publish details that would confuse users. Public interface includes 2 methods.
I can work in TDD style (write small methods step-by-step).
I can cover most of class's functionality using test data, without database connection.
Could somebody describe, what am I doing wrong? What design should I use to obtain the same bonuses and do not test private methods?
UPDATE: It seems to me I've extracted everything I was able to another classes. So, I cannot imagine what could I extract additionally. Loading from database is performed by ORM layer, parsing stream, serializing to XML, running macro - everything is done by standalone classes. This class contains quite complex data structure, routines to search and conversion, and calls for all mentioned utilities. So, I don't think something else could be extracted; otherwise, its responsibility (knowledge about the data structure) would be divided between classes.
So, the best method to solve I see now is dividing into 2 objects (Facade itself and real object, with private methods become public) and move real object to somewhere nobody would try to find it. In my case (Delphi) it would be a standalone unit, in other languages it could be a separate name space. Other similar option is 2 interfaces, thanks for idea.

I think you are putting too many responsibilities (implementations) into the facade. I would normally consider this to be a front-end for actual implementations that are in other classes.
So the private methods in your facade are likely to be public methods in one or more other classes. Then you can test them there.

Could somebody describe, what am I
doing wrong?
Maybe nothing?
If I want to test a method I make it default (package) scope and test it.
You already mentioned another good solution: create an interface with your two methods. You clients access those two methods and the visibility of the other methods don't matter.

Private methods are used to encapsulate some behavior that has no meaning outside of the class you are trying to test. You should never have to test private methods because only the public or protected methods of the same class will ever call private methods.
It may just be that your class is very complex and it will take significant effort to test it. However, I would suggest you look for abstractions that you can break out into their own classes. These classes will have a smaller scope of items and complexity to test.

I am not familiar with your requirements & design but it seems that your design is procedural rather than object oriented. i.e. you have 2 public methods and many private methods. If you break your class to objects where every object has its role it would be easier to test each of the "small" classes. In addition you can set the "helpers" objects access level to package (the default in Java, I know there is a similar access level in C#) this way you are not exposing them in the API but you can unit test them independently (as they are units).

Maybe if you take time and look the
Clean Code Tech talks from Miško. He is very insightfull of how code should be written in order to be tested.

This is a bit controversial topic... Most TDDers hold opinion that refactoring your methods for easier unit testing actually makes your design better. I think that this is often true, but specific case of private methods for public APIs is definitely an exception. So, yes, you should test private method, and no, you shouldn't make it public.
If you're working in Java, here's a utility method I wrote that will help you test static private methods in a class:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import junit.framework.Assert;
public static Object invokeStaticPrivateMethod(Class<?> clazz, String methodName, Object... params) {
Assert.assertNotNull(clazz);
Assert.assertNotNull(methodName);
Assert.assertNotNull(params);
// find requested method
final Method methods[] = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; ++i) {
if (methodName.equals(methods[i].getName())) {
try {
// this line makes testing private methods possible :)
methods[i].setAccessible(true);
return methods[i].invoke(clazz, params);
} catch (IllegalArgumentException ex) {
// maybe method is overloaded - try finding another method with the same name
continue;
} catch (IllegalAccessException ex) {
Assert.fail("IllegalAccessException accessing method '" + methodName + "'");
} catch (InvocationTargetException ex) {
// this makes finding out where test failed a bit easier by
// purging unnecessary stack trace
if (ex.getCause() instanceof RuntimeException) {
throw (RuntimeException) ex.getCause();
} else {
throw new InvocationException(ex.getCause());
}
}
}
}
Assert.fail("method '" + methodName + "' not found");
return null;
}
This could probably be rewritten for non-static methods as well, but those pesky private methods usually are private so I never needed that. :)

suppose you have 8 private methods and 2 public ones. If you can execute a private method independently, i.e. without calling any of the other methods, and without state-corrupting side-effects, then unit testing just that method makes sense. But then in that case there is no need for the method to be private!
in C# i would make such methods protected instead of private, and expose them as public in a subclass for testing
given your scenario, it might make more sense for the testable methods to be public and let the user have a true facade with only the 2 public methods that they need for their interface

Related

Should we create base test class which contains additionals mocks?

When we have a classes like
class IntoController(IViewModelCreator viewModelCreator) {}
and
class ProductController(ICommandFactory commandFactory, IViewModelCreator viewModelCreator) {}
and
class ProductController(ICommandFactory commandFactory, IViewModelCreator viewModelCreator, IRepository repository) {}
and a lot of more. It takes a lot of time to mock this interfaces each time. What do you think about general purpose class which contains a big set of mocks?
class BaseControllerUnitTests
{
protected Mock<IViewModelCreator> ViewModelCreator { get;set; }
protected Mock<ICommandFactory> ViewModelCreator { get;set; }
protected Mock<IRepository> ViewModelCreator { get;set; }
}
Thanks in advance.
I actually do this; I just keep them in a different class called TestDataFactory so I don't get into problems with inheritance (just in case I have to extend some other base class in a test).
The factory shouldn't be global/static (see below).
Pro:
There is a single place for all tests to go to get a valid object graph
If the object graph changes, there is just one place to go to fix all the tests
You can keep references to the mocks in the factory for mocking inner method calls (i.e. you can ask for a ProductController and later, when you ask for an ICommandFactory, you get the one which was injected into the controller).
Con:
The test factory will become quite big. Eventually, you'll have to split it into several files.
Not all tests need the exact same mockup. Sometimes, you'll need to insert a real object. My solution is to allow to override the references which the factory keeps. But it makes the code even more clumsy.
In addition to Aaron Digulla's answer I'd like to suggest my colleague's post with some examples. He calls it Test Context. I use this approach pretty much as well.
The fact that's you're writing test code shouldn't mean that all software engineering best practices should go out the window.
If you have a subset of common functionality between your tests (in this case - mocking some methods of the tested class) then yes, by all means - you can extract a base class.

How to write jUnit tests for private methods [duplicate]

How do I use JUnit to test a class that has internal private methods, fields or nested classes?
It seems bad to change the access modifier for a method just to be able to run a test.
If you have somewhat of a legacy Java application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection.
Internally we're using helpers to get/set private and private static variables as well as invoke private and private static methods. The following patterns will let you do pretty much anything related to the private methods and fields. Of course, you can't change private static final variables through reflection.
Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);
And for fields:
Field field = TargetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
Notes:
TargetClass.getDeclaredMethod(methodName, argClasses) lets you look into private methods. The same thing applies for
getDeclaredField.
The setAccessible(true) is required to play around with privates.
The best way to test a private method is via another public method. If this cannot be done, then one of the following conditions is true:
The private method is dead code
There is a design smell near the class that you are testing
The method that you are trying to test should not be private
When I have private methods in a class that are sufficiently complicated that I feel the need to test the private methods directly, that is a code smell: my class is too complicated.
My usual approach to addressing such issues is to tease out a new class that contains the interesting bits. Often, this method and the fields it interacts with, and maybe another method or two can be extracted in to a new class.
The new class exposes these methods as 'public', so they're accessible for unit testing. The new and old classes are now both simpler than the original class, which is great for me (I need to keep things simple, or I get lost!).
Note that I'm not suggesting that people create classes without using their brain! The point here is to use the forces of unit testing to help you find good new classes.
I have used reflection to do this for Java in the past, and in my opinion it was a big mistake.
Strictly speaking, you should not be writing unit tests that directly test private methods. What you should be testing is the public contract that the class has with other objects; you should never directly test an object's internals. If another developer wants to make a small internal change to the class, which doesn't affect the classes public contract, he/she then has to modify your reflection based test to ensure that it works. If you do this repeatedly throughout a project, unit tests then stop being a useful measurement of code health, and start to become a hindrance to development, and an annoyance to the development team.
What I recommend doing instead is using a code coverage tool, such as Cobertura, to ensure that the unit tests you write provide decent coverage of the code in private methods. That way, you indirectly test what the private methods are doing, and maintain a higher level of agility.
From this article: Testing Private Methods with JUnit and SuiteRunner (Bill Venners), you basically have 4 options:
Don't test private methods.
Give the methods package access.
Use a nested test class.
Use reflection.
Generally a unit test is intended to exercise the public interface of a class or unit. Therefore, private methods are implementation detail that you would not expect to test explicitly.
Just two examples of where I would want to test a private method:
Decryption routines - I would not
want to make them visible to anyone to see just for
the sake of testing, else anyone can
use them to decrypt. But they are
intrinsic to the code, complicated,
and need to always work (the obvious exception is reflection which can be used to view even private methods in most cases, when SecurityManager is not configured to prevent this).
Creating an SDK for community
consumption. Here public takes on a
wholly different meaning, since this
is code that the whole world may see
(not just internal to my application). I put
code into private methods if I don't
want the SDK users to see it - I
don't see this as code smell, merely
as how SDK programming works. But of
course I still need to test my
private methods, and they are where
the functionality of my SDK actually
lives.
I understand the idea of only testing the "contract". But I don't see one can advocate actually not testing code—your mileage may vary.
So my trade-off involves complicating the JUnit tests with reflection, rather than compromising my security and SDK.
The private methods are called by a public method, so the inputs to your public methods should also test private methods that are called by those public methods. When a public method fails, then that could be a failure in the private method.
In the Spring Framework you can test private methods using this method:
ReflectionTestUtils.invokeMethod()
For example:
ReflectionTestUtils.invokeMethod(TestClazz, "createTest", "input data");
Another approach I have used is to change a private method to package private or protected then complement it with the #VisibleForTesting annotation of the Google Guava library.
This will tell anybody using this method to take caution and not access it directly even in a package. Also a test class need not be in same package physically, but in the same package under the test folder.
For example, if a method to be tested is in src/main/java/mypackage/MyClass.java then your test call should be placed in src/test/java/mypackage/MyClassTest.java. That way, you got access to the test method in your test class.
To test legacy code with large and quirky classes, it is often very helpful to be able to test the one private (or public) method I'm writing right now.
I use the junitx.util.PrivateAccessor-package for Java. It has lots of helpful one-liners for accessing private methods and private fields.
import junitx.util.PrivateAccessor;
PrivateAccessor.setField(myObjectReference, "myCrucialButHardToReachPrivateField", myNewValue);
PrivateAccessor.invoke(myObjectReference, "privateMethodName", java.lang.Class[] parameterTypes, java.lang.Object[] args);
Having tried Cem Catikkas' solution using reflection for Java, I'd have to say his was a more elegant solution than I have described here. However, if you're looking for an alternative to using reflection, and have access to the source you're testing, this will still be an option.
There is possible merit in testing private methods of a class, particularly with test-driven development, where you would like to design small tests before you write any code.
Creating a test with access to private members and methods can test areas of code which are difficult to target specifically with access only to public methods. If a public method has several steps involved, it can consist of several private methods, which can then be tested individually.
Advantages:
Can test to a finer granularity
Disadvantages:
Test code must reside in the same
file as source code, which can be
more difficult to maintain
Similarly with .class output files, they must remain within the same package as declared in source code
However, if continuous testing requires this method, it may be a signal that the private methods should be extracted, which could be tested in the traditional, public way.
Here is a convoluted example of how this would work:
// Import statements and package declarations
public class ClassToTest
{
private int decrement(int toDecrement) {
toDecrement--;
return toDecrement;
}
// Constructor and the rest of the class
public static class StaticInnerTest extends TestCase
{
public StaticInnerTest(){
super();
}
public void testDecrement(){
int number = 10;
ClassToTest toTest= new ClassToTest();
int decremented = toTest.decrement(number);
assertEquals(9, decremented);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(StaticInnerTest.class);
}
}
}
The inner class would be compiled to ClassToTest$StaticInnerTest.
See also: Java Tip 106: Static inner classes for fun and profit
As others have said... don't test private methods directly. Here are a few thoughts:
Keep all methods small and focused (easy to test, easy to find what is wrong)
Use code coverage tools. I like Cobertura (oh happy day, it looks like a new version is out!)
Run the code coverage on the unit tests. If you see that methods are not fully tested add to the tests to get the coverage up. Aim for 100% code coverage, but realize that you probably won't get it.
If using Spring, ReflectionTestUtils provides some handy tools that help out here with minimal effort. For example, to set up a mock on a private member without being forced to add an undesirable public setter:
ReflectionTestUtils.setField(theClass, "theUnsettableField", theMockObject);
Private methods are consumed by public ones. Otherwise, they're dead code. That's why you test the public method, asserting the expected results of the public method and thereby, the private methods it consumes.
Testing private methods should be tested by debugging before running your unit tests on public methods.
They may also be debugged using test-driven development, debugging your unit tests until all your assertions are met.
I personally believe it is better to create classes using TDD; creating the public method stubs, then generating unit tests with all the assertions defined in advance, so the expected outcome of the method is determined before you code it. This way, you don't go down the wrong path of making the unit test assertions fit the results. Your class is then robust and meets requirements when all your unit tests pass.
If you're trying to test existing code that you're reluctant or unable to change, reflection is a good choice.
If the class's design is still flexible, and you've got a complicated private method that you'd like to test separately, I suggest you pull it out into a separate class and test that class separately. This doesn't have to change the public interface of the original class; it can internally create an instance of the helper class and call the helper method.
If you want to test difficult error conditions coming from the helper method, you can go a step further. Extract an interface from the helper class, add a public getter and setter to the original class to inject the helper class (used through its interface), and then inject a mock version of the helper class into the original class to test how the original class responds to exceptions from the helper. This approach is also helpful if you want to test the original class without also testing the helper class.
Testing private methods breaks the encapsulation of your class because every time you change the internal implementation you break client code (in this case, the tests).
So don't test private methods.
The answer from JUnit.org FAQ page:
But if you must...
If you are using JDK 1.3 or higher, you can use reflection to subvert
the access control mechanism with the aid of the PrivilegedAccessor.
For details on how to use it, read this article.
If you are using JDK 1.6 or higher and you annotate your tests with
#Test, you can use Dp4j to inject reflection in your test methods. For
details on how to use it, see this test script.
P.S. I'm the main contributor to Dp4j. Ask me if you need help. :)
If you want to test private methods of a legacy application where you can't change the code, one option for Java is jMockit, which will allow you to create mocks to an object even when they're private to the class.
PowerMockito is made for this.
Use a Maven dependency:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.7</version>
<scope>test</scope>
</dependency>
Then you can do
import org.powermock.reflect.Whitebox;
...
MyClass sut = new MyClass();
SomeType rval = Whitebox.invokeMethod(sut, "myPrivateMethod", params, moreParams);
I tend not to test private methods. There lies madness. Personally, I believe you should only test your publicly exposed interfaces (and that includes protected and internal methods).
If you're using JUnit, have a look at junit-addons. It has the ability to ignore the Java security model and access private methods and attributes.
Here is my generic function to test private fields:
protected <F> F getPrivateField(String fieldName, Object obj)
throws NoSuchFieldException, IllegalAccessException {
Field field =
obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (F)field.get(obj);
}
Please see below for an example;
The following import statement should be added:
import org.powermock.reflect.Whitebox;
Now you can directly pass the object which has the private method, method name to be called, and additional parameters as below.
Whitebox.invokeMethod(obj, "privateMethod", "param1");
I would suggest you refactoring your code a little bit. When you have to start thinking about using reflection or other kind of stuff, for just testing your code, something is going wrong with your code.
You mentioned different types of problems. Let's start with private fields. In case of private fields I would have added a new constructor and injected fields into that. Instead of this:
public class ClassToTest {
private final String first = "first";
private final List<String> second = new ArrayList<>();
...
}
I'd have used this:
public class ClassToTest {
private final String first;
private final List<String> second;
public ClassToTest() {
this("first", new ArrayList<>());
}
public ClassToTest(final String first, final List<String> second) {
this.first = first;
this.second = second;
}
...
}
This won't be a problem even with some legacy code. Old code will be using an empty constructor, and if you ask me, refactored code will look cleaner, and you'll be able to inject necessary values in test without reflection.
Now about private methods. In my personal experience when you have to stub a private method for testing, then that method has nothing to do in that class. A common pattern, in that case, would be to wrap it within an interface, like Callable and then you pass in that interface also in the constructor (with that multiple constructor trick):
public ClassToTest() {
this(...);
}
public ClassToTest(final Callable<T> privateMethodLogic) {
this.privateMethodLogic = privateMethodLogic;
}
Mostly all that I wrote looks like it's a dependency injection pattern. In my personal experience it's really useful while testing, and I think that this kind of code is cleaner and will be easier to maintain. I'd say the same about nested classes. If a nested class contains heavy logic it would be better if you'd moved it as a package private class and have injected it into a class needing it.
There are also several other design patterns which I have used while refactoring and maintaining legacy code, but it all depends on cases of your code to test. Using reflection mostly is not a problem, but when you have an enterprise application which is heavily tested and tests are run before every deployment everything gets really slow (it's just annoying and I don't like that kind of stuff).
There is also setter injection, but I wouldn't recommended using it. I'd better stick with a constructor and initialize everything when it's really necessary, leaving the possibility for injecting necessary dependencies.
A private method is only to be accessed within the same class. So there is no way to test a “private” method of a target class from any test class. A way out is that you can perform unit testing manually or can change your method from “private” to “protected”.
And then a protected method can only be accessed within the same package where the class is defined. So, testing a protected method of a target class means we need to define your test class in the same package as the target class.
If all the above does not suits your requirement, use the reflection way to access the private method.
As many above have suggested, a good way is to test them via your public interfaces.
If you do this, it's a good idea to use a code coverage tool (like EMMA) to see if your private methods are in fact being executed from your tests.
Today, I pushed a Java library to help testing private methods and fields. It has been designed with Android in mind, but it can really be used for any Java project.
If you got some code with private methods or fields or constructors, you can use BoundBox. It does exactly what you are looking for.
Here below is an example of a test that accesses two private fields of an Android activity to test it:
#UiThreadTest
public void testCompute() {
// Given
boundBoxOfMainActivity = new BoundBoxOfMainActivity(getActivity());
// When
boundBoxOfMainActivity.boundBox_getButtonMain().performClick();
// Then
assertEquals("42", boundBoxOfMainActivity.boundBox_getTextViewMain().getText());
}
BoundBox makes it easy to test private/protected fields, methods and constructors. You can even access stuff that is hidden by inheritance. Indeed, BoundBox breaks encapsulation. It will give you access to all that through reflection, but everything is checked at compile time.
It is ideal for testing some legacy code. Use it carefully. ;)
First, I'll throw this question out: Why do your private members need isolated testing? Are they that complex, providing such complicated behaviors as to require testing apart from the public surface? It's unit testing, not 'line-of-code' testing. Don't sweat the small stuff.
If they are that big, big enough that these private members are each a 'unit' large in complexity—consider refactoring such private members out of this class.
If refactoring is inappropriate or infeasible, can you use the strategy pattern to replace access to these private member functions / member classes when under unit test? Under unit test, the strategy would provide added validation, but in release builds it would be simple passthrough.
I want to share a rule I have about testing which particularly is related to this topic:
I think that you should never adapt production code in order to
indulge easer writing of tests.
There are a few suggestions in other posts saying you should adapt the original class in order to test a private method - please red this warning first.
If we change the accessibility of a method/field to package private or protected, just in order to have it accessible to tests, then we defeat the purpose of existence of private access directive.
Why should we have private fields/methods/classes at all when we want to have test-driven development? Should we declare everything as package private, or even public then, so we can test without any effort?—I don't think so.
From another point of view: Tests should not burden performance and execution of the production application.
If we change production code just for the sake of easier testing, that may burden performance and the execution of the application in some way.
If someone starts to change private access to package private, then a developer may eventually come up to other "ingenious ideas" about adding even more code to the original class. This would make additional noise to readability and can burden the performance of the application.
With changing of a private access to some less restrictive, we are opening the possibility to a developer for misusing the new situation in the future development of the application. Instead of enforcing him/her to develop in the proper way, we are tempting him/her with new possibilities and giving him ability to make wrong choices in the future.
Of course there might be a few exceptions to this rule, but with clear understanding, what is the rule and what is the exception? We need to be absolutely sure we know why that kind of exception is introduced.

How to unit-test private code without refactoring to separate class?

Assume i have a private routine that performs some calculation:
private function TCar.Speed: float
{
Result = m_furlogs * 23;
}
But now i want to begin testing this calculation more thoroughly, so i refactor it out to a separate function:
public function TCar.Speed: float
{
Result = CalculateSpeed(m_furlogs);
}
private function TCar.CalculateSpeed(single furlogs): float
{
Result = furlogs * 23;
}
Now i can perform all kinds of tests on CalculateSpeed:
Check( CalculateSpeed(0) = 0);
Check( CalculateSpeed(1) = 23);
Check( CalculateSpeed(2) = 46);
Check( CalculateSpeed(88) = -1);
Except that i can't perform these tests, because CalculateSpeed is private to TCar. An abstract tennant of unit-testing is that you never test private code - only public interfaces. As a practical matter, *x*Unit is not normally structured to be able to access private methods of the separate class being tested.
The issue is that none of the rest of the class is setup to handle unit-tests. This is the very first routine that will have testing of any kind. And it is very difficult to configure the host class a set of initial conditions that will allow me to test calling CalculateSpeed with every set of inputs that i would like.
The only alternative i can see, is moving this private calculation out into it's own TCarCalculateSpeed class:
public class TCarCalculateSpeed
{
public function CalculateSpeed(float furlogs)
{
Result = furlogs * 23;
}
}
A whole class, dedicated to exposing one method, that's supposed to be private, just so i can test it?
Class explosion.
Plus it's private. If i wanted it to be public, i'd rather promote it to public visibility - at least that way i save a separate class being created.
i'd like to add some unit-testing; but it can only be done in small pieces, as code changes. i can't completely redesign functioning 12 year old software, possibly breaking everything, because i wanted to test one internal calculation.
My current, best, thinking is to add a Test method to my Car class, and just call that:
TCar Car = new TCar();
Car.RunTests;
public procedure TCar.RunTests
{
Check( CalculateSpeed(0) = 0);
Check( CalculateSpeed(1) = 23);
Check( CalculateSpeed(2) = 46);
Check( CalculateSpeed(88) = -1);
}
But now i have to figure out how to have TCar.RunTests get trigged by the external TestRunner, which is only designed to use TestCase classes.
Note: i've tried my damnest to mix syntax from a bunch of languages. In other words: language agnostic.
This can't really be quite language-agnostic, as the protection mechanisms and the tactics to bypass them vary quite widely with language.
But most languages do provide bypasses in some form, and as others have noted, there are sometimes protections midway between private and public that make testing easier.
In Java, for example, reflection can be used to private stuff if you really need to, and things can be made protected or package-private so that you don't need reflection.
Generally speaking, if something is complex enough to require testing it should not be buried as a private method or class in something else. It is doing something that warrants its own class.
Rather than worrying about the number of classes, worry about their size and complexity. Many small classes adhering to the Single Responsibility Principle are better than a small number of classes doing complex things internally.
If a method is complicated (and risky) enough to test on its own, it's worth creating a class for it or making it a public member of the existing class - whichever is more suitable, given the characteristics of the existing class.
Can you create multiple instances of the TCar class with different initial values of m_furlogs? Do you have a getter on speed anywhere? You could validate against that if so.
If it's only internally used, and you really want to test it, you could create a utilities class that holds the logic for the simple calculations. I know it's refactoring, but it's not the class explosion you might be envisioning.
In some languages, there is middle ground between private and public. You can expose a logically private method to a unit test without exposing it to the world.
In method documentation, you can document that the method is intended private, but accessible for the purpose of unit-testing.
In Java, for example, you could make the private method package protected, and place the unit test in the same package. In C#, if I recall correctly, you could make it internal. In C++, the unit-test could be a friend.
If your language supports compiler defines, you could use these to your advantage.
(Example code in Delphi)
In your unit test project, set a compiler conditional define, either using the project options or in an include file that you include in each and every unit in that project.
{$DEFINE UNIT_TESTS}
In your class code, check the conditional define and switch between public or protected and private accordingly:
{$IFDEF UNIT_TESTS}
public // or protected
{$ELSE}
private
{$ENDIF}
function CalculateSpeed: float;
This means your unit tests will have the access they need to your method, while in production code it will still be private.

How to unit test private methods in BDD / TDD?

I am trying to program according to Behavior Driven Development,
which states that no line of code should be written without writing
failing unit test first.
My questions:
how to use BDD with private methods, and
how can I unit test private methods?
Is there better solution than:
making private methods public first and then making them private
when I write public method that uses those private methods;
or
in C# making all private methods internal and using InternalsVisibleTo
attribute.
When you write code test-first, you write against the public interface. There are no private methods at this point.
Then you write the code to pass the test. If any of that code gets factored into a private method, that's not important -- it should still be there only because it is used by the public interface.
If the code isn't written test first, then -- in .net, anyway -- reflection can be used to directly prod private methods; though this is a technique of last resort.
Private methods are internal implementation details. They should not be tested directly, as they will be tested indirectly via testing your public interface. If for some reason a private method is not covered when your public interface is fully tested, then the private method is not required, and it should be removed.
Generally, it is a bad idea to bind test code to private implementation details. That couples your test to those private details, reducing your freedom to change those details at will, even if they don't affect the publicly facing interface and behavior. That increases the amount of effort required to write and maintain your unit tests, which is a negative thing. You should strive for as much coverage as possible, while only binding to the public interface.
Short answer: You don't test private methods.
If you have programmed well, the code coverage of your tests should be testing private methods implicitly.
If a private method method exists, it's there to be used by a public method. Therefore I'd write a test for the public method.
I write my tests to test the public parts of a class. If the class is well designed then the private parts get tested by default.
If the private method isn't called from a public method, then why does it exist?
In your case I'd do the following
* Write failing test for the public method
* Write public method that calls the private method that doesn't exist yet(test still fails as your class is incomplete
* Write the private method
* Test should now pass
Short answer: You can't test a private method.
Long answer: You can't test a private method, but if you're inclined to test whatever it does consider refactoring your code. There are two trivial approaches:
Test the public method that accesses the private method.
Extract the private code to its own class, i.e. move the implementation so it can become appropriately public.
The first one is simple but has a tendency to let you shoot your own foot as you write more tests and the latter promotes better code and test design.
Contrived answer: Okay, so I lied. You can test a private method with the help of some reflection magic (some TDD tools support testing private methods). In my experience though, it leads to convoluted unit tests. Convoluted unit tests leads to worse code. Worse code leads to anger. Anger leads to hate. Hate leads to suffering…
The direct effect of production code becoming worse is that the class under test tend to become large and handles many things (violation of Single Responsibility Principle) and harder to maintain. This defeats the purpose of TDD, that is to get production code testable, extensible and more importantly: reusable.
If you're writing tests for a class that is deployed, you could investigate everything that calls the private method and write tests accordingly. If you have the chance to rewrite the class then please do refactor it by splitting the class up. If you're lucky then you'll end up with some code reuse that you can utilize.
We can Unit Test static and instance private methods using PrivateType and PrivateObject respectively. The following 2 articles explains these techniques
1. Unit Test Private Static Method in C#.NET
2. Unit Test Private Instance Method in C#.NET
I agree with the point that has been made about not testing private methods per se and that tests should be written against the public API, but there is another option you haven't listed above.
You could make the methods protected then derive from the class under test. You can expose the base protected method with a public method on the derived class, for example,
public class TestableClassToTest : ClassToTest
{
public new void MethodToTest()
{
base.MethodToTest();
}
}
You might be using this Extract and Override pattern already to override virtual properties of the base class for dependency injection, in which case this may be a viable option for you.
Mbunit Reflector helps you with this.
Reflector objectReflection = new Reflector(new ObjectWithprivateMethods());
objectReflection.InvokeMethod(AccessModifier.NonPublic,,"Add",1,6));
A blog post about it.
I've been fighting with it for over 1 month, but found the answer:
var objectOfPrivateMethod = new ObjectOfPrivateMethod(); //yes here is contructor
object[] arguments = { }; // here as Object you provide arguments
var extractedPrivateMethod = typeof(ObjectOfPrivateMethod).GetMethod("Name_Of_Private_Method", BindingFlags.NonPublic|BindingFlags.Static); //if fails returns null. delete flag static if it's not static. Returns your method as an object.
Assert.AreNotEqual(null, extractedPrivateMethod, "Mathod does not exist"); // good to catch if even exists.
object result = extractedPrivateMethod.Invoke(null, arguments); // here as object you'll get return value of your function. change null for object of class where is method, if your method is not static
that's all.
You should only be testing the external API of your classes, i.e. the public methods. If your tests aren't hitting code in the private methods then either you need to write more tests or refactor the class.
The whole point of testing an API, especially one that will be distributed to third parties, is that you can change the internal structure of the class as much as you want, as long as you don't break the external contract of it's public methods.
As you've identified, this is where BDD comes into play over 'traditional' TDD using mock classes, where every method call has to be set-up in advance for the test. I'm not an expert on either of these, hopefully someone else can answer that one better than I can.
If you find yourself wanting to test a private method then there is something complex in it and you are probably right to want to test it, this is a design smell. Exposing the method on the interface just swaps one smell for another worse one.
Time to refactor :)
Usually I factor out the inner complexity into a helper class. However check the method for 'Feature Envy' or 'Inappropriate Intimacy'. There may be a better place for the method to live. With Extension methods in .net now, even base types could be a good candidate.
Good Luck
If you really believe that a private method is complex enough that it deserves unit tests of it's own - it's an indicator that your class is doing too much and you should extract part or all of that private method into a class of its own behind an interface.
Mock the interface when testing the original class. You should now have a public accessor to the new class which was previously the private method.
Sometimes when dealing with old code that was either poorly written or not written using TDD there may be a need to test the private classes. In this case you should use reflection, but where possible update the code to follow closer to the TDD approach.

TDD: Which methods do you expose for unit testing?

There is one aspect of TDD which I never fully understood.
Suppose somebody asked you to implement a simple Stack object. If you've done your design properly, you will come to a very minimal and clean API. Suppose: push(), pop() and isEmpty(). Anything more than that is over-killing the demand, and allowing the user too much room to mess with your code.
So now let's suppose you want to unit test your code. How do you go about doing this if all your public methods are just the three shown above? Those methods will take your testing only so far.
So either you add private methods, which do not help you at all since they are not visible to your unit test case. Or you make those methods public and there goes your minimalistic API which you worked on so hard. Now the user is going to mess with your Stack and the bugs will be sure to come.
How do you handle this dilemma of opening public methods for testing vs. a clean and simple API?
Edit: just to point in the right direction, It would be nice to get technical pointers (such as "use this hack to expose private methods", etc...) but I am much more intrested in more generic answers as to what of the two concepts is more important, and how you approach this subject.
test the features; this usually means testing the public interface - for should not all features be accessible via the public interface? if they aren't, then they aren't features! There may be exceptions to this, but i can't think of any.
test the public interface; any methods that are not called directly or indirectly from the public interface are not necessary. Not only do they not need to be tested, they do not need to exist at all.
You should take a look at that question : do you test private method?.
To not break the encapsulation, I find that the private method is huge or complex or important enough to require its own tests, I just put it in another class and make it public there (Method Object). Then I can easily test the previously-private-but-now-public method that now lives on it's own class.
Using your Stack example, you really shouldn't need to expose any inner workings to unit test it. Reiterating what others have said, you should feel free to have as many private methods as needed, but only test through your public API.
[Test]
public void new_instance_should_be_empty()
{
var stack = new Stack();
Assert.That(stack.IsEmpty(), Is.True);
}
[Test]
public void single_push_makes_IsEmpty_false()
{
var stack = new Stack();
stack.Push("first");
Assert.That(stack.IsEmpty(), Is.False);
}
Using a combination of pushing and popping you can simulate all behaviour of the Stack class, because that's the only way a user has to interact with it. You don't need any tricks because you should only be testing what others can use.
[Test]
public void three_pushes_and_three_pops_results_in_empty_stack()
{
var stack = new Stack();
stack.Push("one");
stack.Push("two");
stack.Push("three");
stack.Pop();
stack.Pop();
stack.Pop();
Assert.That(stack.IsEmpty(), Is.True);
}
Sometimes I make methods which would otherwise be private into package level (Java) or internal (.NET) methods, usually with a comment or an annotation/attribute to explain why.
Most of the time, however, I avoid doing this. What would the public API not let you test in your stack case? If the user can see the bug and they're only using the public API, what's stopping you from making the same calls?
The times I expose otherwise-private methods is when it makes it easier to test one part of a complicated set of steps in isolation - if a single method call is very "chunky" it can be very helpful to test each step in isolation, even though the steps shouldn't be visible to a normal user.
right TDD is all about testing behavior which could be tested by public interface... if there are are any private methods then those methods should be indirectly tested by any public interface...
With TDD, all of your code should be reachable from your public interface:
First you write the tests for your features.
Then you write the minimum amount of code for your tests to pass. This is the indication that your features are implemented.
If some code is not covered, this means that either this code is useless (remove it and run your tests again) or your tests are incomplete (some features have been implemented but not explicitely identified by a test).
You can test private with Reflection but it will be a pain later. I think you need to put your test in the same assembly (or package) and try to use Internal. This way you have some protection and you can test your stuff that you want to test.
If your private method is not indirectly tested by the public API test methods and it needs to be tested then I would delegate your main class to another secondary class.
public Stack {
public ... push(...) {...}
public ... pop(...) {...}
public ... isEmpty(...) {...}
// secondary class
private StackSupport stackSupport;
public StackSupport getStackSupport() {...}
public void setStackSupport(StackSupport stackSupport) {...}
}
public StackSupport {
public ...yourOldPrivateMethodToTest(...) {...}
}
Then your private method is a public method in another class. And you can test that public method in the another class tests. :-)
When coding using TDD, I create the public interface API for the object. That would mean in your example that my interface which the class implements would only have push(), pop() and isEmpty().
However testing these methods by calling them aren't unit tests in themselves (more on this at the end of this post), since they most likely test the co-operation of multiple inner methods which together produce the desired result and this is what your question is about: Should those methods be private?
My answer is no, use protected (or the equivalent of it in the language of your choice) for those instead of private which means that if your project and test POMs are structured similarly, the test suite class can see inside the actual class since they're virtually in the same folder. These can be considered unit tests: You're testing functional blocks of the class itself, not their co-operation.
As for testing the individual interface/API methods it's of course important to do that too and I'm not disputing that, those however fall somewhere between the hazy line of unit testing and acceptance testing.
In my opinion the most important thing to remember here is that unit tests tell you if a method misbehaves, acceptance tests tell if the co-operation of multiple methods'/classes' misbehave and integration testing tells if multiple systems' co-operation misbehaves.