Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guava @VisibleForTesting : Help me with a complete example

My intent is to do unit test of private methods and I understand on how to import the @VisibleForTesting and use it for a private method. I have done a quite a bit of search but unable to see a complete example that demonstrates this feature.

For eg:

class MyClass {
    @VisibleForTesting 
    private double[] getWorkArray(double[] values,int length) {
               :
               :
        return <some double array> 
    }
}

Now in JUnit, I must be able to do

@Test
public void testProvateMethod() {
    MyClass object = new MyClass();
    assertNotNull(object.getWorkArray(...);
}

But the difficult part is I am unable to comprehend/do the following a) Snippet of maven compiler plugin for including the relevant annotation processor b) Actually be able to test a private method. (since it throws error related to visibility of method)

I am unable to do it in action while I write a test in JUnit (due to the private access error). For eg: mvn clean test

Please provide a complete example to really all steps involved in getting the JUnit test of private methods done.

like image 460
user3709525 Avatar asked Jun 05 '14 04:06

user3709525


People also ask

What is @VisibleForTesting used for?

Stay organized with collections Save and categorize content based on your preferences. Denotes that the class, method or field has its visibility relaxed, so that it is more widely visible than otherwise necessary to make code testable.

How do you test private methods?

To test private methods, you just need to test the public methods that call them. Call your public method and make assertions about the result or the state of the object. If the tests pass, you know your private methods are working correctly.

What does visible for testing annotation do?

Annotation Type VisibleForTestingAnnotates a program element that exists, or is more widely visible than otherwise necessary, only for use in test code.


2 Answers

Firstly, I do not recommend to test private methods, unit tests should test public methods in most cases. If you have to test private methods, it usually indicates a bad design.

Regarding to @VisibleForTesting , it is used in package-methods in Guava, and not part of JUnit API. The annotation is just a tag to indicate the method can be tested, it even doesn't be loaded in JVM. So if you need to test non-public methods, make the methods package scope which is visible to unit test classes in same package.

Last, by using reflect can access private methods, if you really have to test them.

like image 142
卢声远 Shengyuan Lu Avatar answered Sep 23 '22 06:09

卢声远 Shengyuan Lu


Testing a private method must be one of the bad patterns. However, there are times when you often feel the urge to test private methods. In this case, I personally use ReflectionTestUtils to test the method. This is because we wanted to keep the original intent of the private method, and only test the method. Below is an example of my sample.

MyClass myClass = new MyClass();  ReflectionTestUtils.invokeMethod(myClass, "getWorkArray", values, length); 

One drawback is the fact that I get the name of the method as a String and it is quite a bit sad except for the fact that refactoring does not convert correctly in IDEA.

I hope it helps.

Thanks.

like image 29
Dark Avatar answered Sep 23 '22 06:09

Dark