Good object oriented design example in Java - java

I have a Java class called TestExecutor which responsible for starting a test. Starting the test involves a number of stages:
- Update test repository
- Locate the test script
- Create result empty directory
- Execute command
- Parse output
- Update database
For each of these stages I have created private methods in the TestExecutor class which perform each of the actions above, all surrounded in a try-catch block. I'm aware that this is not good design as my class does too much and is also a pain to unit test due to a large amount of functionality being hidden in private methods.
I'd like to hear your suggestions for refactoring this class as I'm not sure how to get away from something similar to the above structure. Code example below:
public void start() throws TestExecuteException {
try {
updateRepository();
locateScript();
createResultDirectory();
executeCommand();
parseOutput();
updateDatabase();
catch(a,b,c) {
}
}
private updateRepository() {
// Code here
}
// And repeat for other functions

I would do this way. First, enforce the contract that each test step should have.
interface TestCommand{
void run();
}
Now make your test commands as separate classes. Try to make these commands classes generic so that you reuse for similar types of commands. Now in your class where you want to run a test, configure the test steps as following.
//in your test class do this.
List<TestStep> testCommands = new ArrayList<>();
testCommands.add(new UpdateRepoCommand());
testCommands.add(new LocateScriptCommand());
// and so on....
Now, execute all your steps chronologically.
public void start(testSteps) throws TestExecuteException {
try {
for(TestCommand command : testCommands){
command.run()
}
catch(Exception e) {
//deal with e
}
}
Moreover, as CKing described above, follow SOLID principle inside those test steps. Inject dependencies and write the unit test for them separately.

Well your class looks ok to me.
I'm aware that this is not good design as my class does too much
As far as the class has a single responsibility the number of methods don't matter.
Check this template method design pattern. Your class is doing something similar to what the abstract Game class is doing.
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
//template method
public final void play(){
//initialize the game
initialize();
//start game
startPlay();
//end game
endPlay();
}
}
and is also a pain to unit test due to a large amount of functionality
being hidden in private methods
Read this & this about testing private methods. You can also use a framework like PowerMock which helps you in testing untestable code.

I'd like to hear your suggestions for refactoring this class as I'm not sure how to get away from something similar to the above structure
You should definitely take a look at the SOLID principles as a starting point to writing clean,testable object oriented code. I was introduced to it at the begning of my career and it really helps a lot to follow these principles.
That said, I would start by grouping related functionality into different classes. For example, updateRepository() and updateDatabase() can be moved to a separate class called DatabaseHelper. Similarly locateScript() and createResultDirectory() seem to be disk related operations and can be moved to a seperate class called DirectoryHelper. I believe you get the gist of it. What you just achieved was Seperation of Concerns.
Now that you have separate classes, you need to bring them together and put them to work. Your TestExecutor can continue to have the methods that you have listed. The only different will be that these methods will now delegate their work to the individual classes that we created above. For this, TestExecutor will need a reference to the DatabaseHelper and DirectoryHelper classes. You could just instantiate these classes directly inside TestExecutor. But that would mean that TestExecutor is tightly coupled to an implementation. What you can do instead is ask code outside TestExecutor to supply the DatabaseHelpe and DirectoryHelper to use. This is known as Dependency Inversion through Dependency Injection. The advantage of this approach is that you can now pass any subclass of DatabaseHelper and DirectoryHelper to TaskExecutor and it doesn't have to know the details of the implementation. This facilitates in the unit testing of TaskExecutor by mocking these dependencies instead of passing actual instances.
I will leave the rest of the SOLID principles for you to explore, implement and appreciate.

Related

How to access a private List object of another object for testing in java [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.

If I have multiple JUnit test classes, but they share a large amount of setup, is there a way to resuse some of this setup code?

I have a number of classes I'm testing, and I've seperated all of the tests for these classes out into their own files. i.e. I have the following sort of directory structure
src
ClassOne.java
ClassTwo.java
test
ClassOneTests.java
ClassTwoTests.java
I have a much larger number of classes to test than this however. I've started to write tests for many of these classes, and I realised that there is a lot of code in the setup that is the same between them all. I'd like to be able to reuse this code, both to reduce the time it takes to write more tests, but also in the event that I end up making modifications to my code base, I want to only have one point in the tests to change, rather than many dozens of almost identical instatiation of mocks.
An example of my code layout is like this:
public class ClassOneTests {
//Declare global variables that are dependencies for the test
AClass var1;
// etc...
ClassOne testThis;
#Before
public void setUp() throws Exception {
//instantiate and populate the dependencies
var1 = new AClass();
// etc...
testThis.setDependencies(var1, //And other dependencies....);
}
#Test
public void aTest() {
//Do test stuff
Var result = testThis.doStuff();
Assert.NotNull(result);
}
// etc...
}
This means a huge majority of stuff in my declaration and setUp method is duplicated across my class tests.
I have partially solved this by simply having a GenericTestSetup.java that does all of this setup and then each ClassXTest.java extends it. The problem lies with the few classes that are unique to each ClassXText.java file, but used in each method. So, in the example above AClass is a variable specific for ClassOneTests. When I do ClassTwoTests I'd have a bunch of shared variables, but then instead of AClass I'd have BClass, for example.
The problem I'm having is that I can't declare two #Before tags, one in the GenericTestClass for the generic setup, and then another in the ClassXTest class if any of the objects inside ClassXTest are dependant on something in GenericTestClass because you can't guarantee an execution order.
In summary, is there a way to have this generic test setup that's used for multiple class tests, but also have another setup method for each specific class that is guaranteed to run after the generic objects have been set up?
EDIT: It was suggested that my question is a duplicate of this question: Where to put common setUp-code for differen testclasses?
I think they're similar, but that question was asking for a more general approach in terms of policy, I have a more specific set of requirements and asking for how it would actually be implemented. Plus, none of the answers there actually gave a proper answer about implementation, which I require, so they're not useful to me.
What i usually do when overloading increases the complexity, I use, what i call Logic classes...
Basically class with static methods which takes the parameters that need to be initialized, and sets them up.
Logic.init(param1, param2)
and I usually use only one #Before with different logic methods.
Advantage is that the code might be shared between similar initializations, and you can reuse the code in the Logic class itself. Example
Logic.init(param1,param2,param3) can call Logic.init(param1,param2), and you can use different variants into the different #Before methods.
EDIT:
I do not know if there is pattern, or a name related to such solution. If there is i would like to know the name as well :).
You could use Template Method pattern. The #before method in the generic class calls a protected method in the same class which is empty but can be overriden in the implementing classes to add specific behaviour.

Code refactoring: Outsourcing substeps to helper classes

When a class performs a complicated and lengthy task, I usually refactor it step-by-step based on the situation, as shown below.
Version 0
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
// lots of complicated code
}
}
Version 1:
Break it down into multiple smaller sub-tasks
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
init();
doSubStepA();
doB();
doC();
wrapUp();
}
}
Version 2:
If complicated enough, outsource sub-tasks to helper classes. I don't really code to interfaces in this case.
public class ComplicatedTaskDoer{
public void doComplicatedTask(){
init();
subsetpADoerClass.doA();
classB.doB();
classC.doC();
wrapUp();
}
}
Version 3:
If I see my self in need of adding more components in the future and if there's a valid pattern in terms of input and output objects, I do the following.
public class ComplicatedTaskController{
//injected
List<SomethingHelperComponent> components;
public void doComplicatedTask(){
init();
for(SomethingHelperComponent component : components){
component.process(commonInput);
}
wrapUp();
}
}
I'm more curious about the version 3. I ended up doing that quite a few times.
Q1)
Is there any existing pattern that's similar and probably more effective? It's not 'chain of responsibilities' that I'm looking for as I prefer those components to be independent (open to discuss). It looks more like a configurable variation of template method pattern.
Q2)
I've always named the main class as 'SomethingController' and the helper classes with 'SomethingHelper' or 'SomethingComponent'. I recently realized that 'controller' was misleading and 'helper' was non-informative.
It'd be really helpful to get some ideas on correctly naming those classes. How'd you name them?
Q3)
Did you think that the refactoring was reasonable?
Q4)
Subjective: Is it OK to keep some steps in the helper methods and outsource some steps to helper classes? I usually restrain myself from unit-testing non-public methods.
Q5)
Do you consider helper classes, i.e. with no code-to-interfaces, to be a code smell? May be I can even declare them as inner classes?
Configuration of classes
This is legit solution. It is sometimes seen with spring where partial tasks
implement some interface and through spring magic you can have list of all implementations with
#Autowired
List<MyInterface> myParts;
Design Pattern Name
As for naming I think you could think about it as as special case of chain of responsibility. It might not be really accurate, but shows your intention pretty well.
Naming of classes
I'd go for suffix .*Algorithm
Name main Interface like DoSomethingComplicatedAlgorithm or DoSomethingComplicatedAlgorithmStep. Classes which implement interface would be called WhatPartOfAlgorithmIsUsedHere
Helper Classes
If they they'll let you avoid code duplication and you have no better domain model than you can use them. On the other hand leave it as a last resort option. Might be small code smell, but certainly your application won't burn.

Junit testing for following scenario

Consider the following class
public class Validator {
boolean startValiadation(UserBean user){
//This method is visible inside this package only
return validateUser(user);
}
private static boolean validateUser(UserBean user){
//This method is visible inside this class only
boolean result=false;
//validations here
return result;
}
}
Due to security requirement of above method I did code in above way. Now I want to wrote test cases using Junit. But generally a unit test is intended to exercise the public interface of a class or unit. Still I can use reflection to do some thing what I am expecting here. But I want to know is there any other way to achieve my goal?
But generally a unit test is intended to exercise the public interface of a class or unit.
Well, I don't get too dogmatic about that. I find that often you can get much better testing depth if you're willing to be "white box" about it, and test non-public members. There's a sliding scale though - testing private members directly is relatively ugly, but you can test package private methods easily, just by making sure your test is in the same package as the class.
(This approach also encourages package private classes - I find that if you're rigidly sticking to testing just the public API, you often end up getting into the habit of making all classes public and many methods public when actually they should be package private.)
In this case, I would suggest you test via the startValiadation method. Currently that calls validateUser but ignores the result - I would assume that in the real code it calls the method and does something useful with the result, which would be visible from the test. In that case, you can just call startValiadation with various different User objects and assert which ones should be valid.
You don't need reflection. Just put your test class in the same package as this class. It doesn't need to be in the same folder or the same project to do that.
No you have only three choices to test a private method:
If you are in control of the code, then change the access specifier to public just to test the method
Otherwise use reflection.
This may be of your interest:
3 . Use a public method to test your private method.
Don't test this class in isolation. A unit test, at least in the spirit of TDD as envisioned by Kent Beck, is not a test for a single class or method, but is simply a test that cannot have side effects on other tests.
This Validator class is used in other classes within the same package. First write a failing test using the public interface of those classes, then make it pass by implementing the validation. No reflection needed.
If you would test this class in isolation, you would probably mock this class in the other classes and verify that startValiadation() is really called. This has the disadvantage of coupling your test code to your implementation code. I would say: don't do that.
I recently wrote a post about this, at the bottom there's a link to a presentation by Ian Cooper that goes deeper into this.

How to unit test a private functionality

I have a question regarding unit testing.
I have a function which does the following thing:
void myFunction(List<MyClass> myList) {
// 1. Sort the list
// 2. Post Process the list
}
Now I want to test this function. But the problem is I should not test these two things at the same time. I am therefore thinking to extract the "Post Process the list" part as a separate function.
But the problem is the task of "Post Process the list" is only used by myFunction and I want to make it private to the class.
If I make it private I won't be able to test it from outside.
What is the general rule of this kind of scenario? Must I change a private function to public only for testing?
Or if there are any other patterns I should use?
Many thanks
The test method only needs to be package-local.
You can call private methods using reflections and there are mocking libraries which allow you to test private methods. But I would just make it package-local as it shows the method is access from elsewhere in the package (which it is either way)
As others have said, you don't need to make the method public, just package visible.
Google Guava has a #VisibleForTesting annotation which is meant for situations like this. You put this annotation on a method, just to document that the reason that the method isn't private is only for testing. The annotation doesn't do anything, it's just meant as a warning for programmers that they shouldn't call it from outside the class. (Some static code checking tool could in principle check if methods with this annotation aren't called from anywhere except inside the class or from test code).
Ofcourse it's kind of ugly to have to modify your code to do this just for testing. If you want to avoid this, you can do tricks with reflection to call the private method:
public class Sandbox {
public static void main(String[] args) throws Exception {
Example e = new Example();
Method m = Example.class.getDeclaredMethod("myFunction", List.class);
m.setAccessible(true);
m.invoke(e, Arrays.asList("one", "two", "three"));
}
}
class Example {
private void myFunction(List<String> data) {
System.out.println("Hey, what are you doing! " + data);
}
}
In general, you should always test the functionality through public methods. If there is some functionality in private methods, which cannot otherwise be tested well enough, that's an indication that the method has a responsibility which should be moved to its own class (this also helps to achieve high cohesion). Then that newly extracted class can be tested directly though its public methods.
Another vote for package-local. Just ensure that your newly exposed method is clearly named and documented so that in future it is not called inappropriately.
It depends.
Dose the sub routine contains common behavior that you should extract ?
Take your first sub routine as example. If you're not sorting your list by Comparator<T>, you should refactor it, then test that Comprartor<T> class instead of your private method. If Post process are actually some algorithm or common business logic, you might want to refactor it using Strategy pattern then test those class you just extract.
The point is, if a private method is complex enough to require a unit-test, then chance is probably you should not put them there, otherwise you should just test through it's public API.
It's a legacy system, and it will take forever to refactor that method.
check Bad Smells in Code : Long method for long method refactor, Method Object is a good strategy for things like this.
It's fine, I just want to test them.
Then you can test through Java reflection API, and I believe there are some mocking framework like PowerMock can also help you.
Below things you may consider for testing a private method.
1.create public method written only for the purpose of testing. (or)
2.create nested class for testing (or)
3.use reflection to test it.
useful link,another useful link from stackoverflow
I typically consider private methods to be part of the method under test. They typically consist of code that has been moved out of the original method to make it leaner and shorter, and more modular. However from a test perspective you would be testing the same code if you moved the content of the private method into your method under test.
The question of trying to isolate the return values of private methods to simulate various conditions is is often valid though. I think its' part of the larger question of how to write testable code.
One approach with very little overhead is to rely on basic overriding of methods. You can make your private methods protected virtual instead, and override them in your test:
Here's an example of that too :
http://www.unit-testing.net/CurrentArticle/How-To-Remove-Data-Dependencies-In-Unit-Tests.html
The example is C#, but the concept applies to all object oriented languages

Categories

Resources