[JAVA] If you want to satisfy the test coverage of private methods in JUnit

At times like this

I really want to make 100% coverage including private methods in JUnit! (Basically, it is more natural to pass all through the public method test)

For example

Suppose there is a private method in the following class that cannot pass the test naturally in only one place. (It's cute that the contents are squishy)


private String getStatus(String param, TestEntity testEntity) {
  String result = null;
  switch (param) {
    case "1":
      result = "A" + testEntity.getCode();
      break;
    case "2":
      result = "B" + testEntity.getCode();
      break;
    case "3":
      result = "C" + testEntity.getCode();
      break;
    default :
 result = "Z" + testEntity.getCode (); // ← The coverage here does not pass!
  }
  return result;
}

How to respond

Use Mockito https://site.mockito.org/

Preparation

In my case, Spring Boot and JUnit have already been installed, so Add the following to dependency to get Mockito library.

When using Maven

<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.10.19</version>
    <scope>test</scope>
</dependency>

If you use Gradle

dependencies {
  // https://mvnrepository.com/artifact/org.mockito/mockito-all
  testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
}

How to use

Just write the following in the test class


  private SampleUtil sampleUtil;

 private static int testId = 1; // Variables used in later validation

  @Test
  public void getStatus() {

 // Set to be able to execute SampleUtil # getStatus
    Method method = SampleUtil.class.getDeclaredMethod("getStatus", String.class, TestEntity.class);
    method.setAccessible(true);

 // Parameter settings for testing
    String param = "4"; 
    TestEntity testEntity = new TestEntity();
    testEntity.setCode("001");

 // Test run
    String status = (String) method.invoke(sampleUtil, param, testEntity);
    assertThat(status, is("Z001"));
  }

By setting accessible = true for getStatus () method of SampleUtil, it is possible to call it ignoring the accessor level.

Advanced version

If you want to get or set a private variable in your test

The following testId is a variable defined private in SampleUtil.java. Let's get it here.


  @Test
  public void getParams() {
    SampleUtil sampleUtil = new SampleUtil();
    assertThat(Whitebox.getInternalState(sampleUtil, "testId"), is(1));
  }

By implementing in this way, it is possible to call while ignoring the accessor level.

Finally

In addition to the functions introduced here, it has many functions such as rewriting static methods and expanding the range of JUnit tests. If you are interested, you may want to dig in and check it out.

Recommended Posts

If you want to satisfy the test coverage of private methods in JUnit
Test private methods in JUnit
Test private methods in JUnit
If you want to recreate the instance in cloud9
If you want to include the parent class in Lombok's @builder
[Swift] When you want to know if the number of characters in a String matches a certain number ...
How to test private methods with arrays or variadic arguments in JUnit
[RSpec] When you want to use the instance variable of the controller in the test [assigns is not recommended]
Get the name of the test case in the JUnit test class
What to do if you can't get the text of an element in Selenium
Things to keep in mind when testing private methods in JUnit
How to mock some methods of the class under test
When you want to change the MySQL password of docker-compose
What to do if you don't see the test code error message in the terminal console
[Java] Test private methods with JUnit
ProxyFactory is convenient when you want to test AOP in Spring!
[PostgreSQL] If you want to delete the Rails app, delete the database first!
If you want to change the Java development environment from Eclipse
Rails' Private methods hurt if you feel the same as Java!
I want to change the value of Attribute in Selenium of Ruby
What to do if you forget the root password in CentOS7
If you just want to run your containers in the cloud, Azure Container Instances is easy
If you want to mock a method in RSpec, you should use the allow method for mock and the singleton method.
A memo when you want to clear the time part of the calendar
How to filter JUnit Test in Gradle
If you want to dynamically embed values & add text to attribute values in Thymeleaf 3
How to test private scope with JUnit
I want you to use Enum # name () for the Key of SharedPreference
[Rails + Webpacker] I want to use images of assets! Until you can view the image in Vue.js
You may not want to use the remove method in ArrayList very often
Be careful about upgrade if you use | etc. in the URL of Tomcat
If you are using Android Room and want to change the column definition
I want to output the day of the week
If you want to modify database columns etc.
When you want to bind InputStream in JDBI3
JUnit 5: How to write test cases in enum
I want to var_dump the contents of the intent
When you want to use the method outside
I want to get the value in Ruby
What to do if you get an Argument Error: wrong number of arguments (given 2, expected 0) in your RSpec test
Summary of copy and paste commands used when you want to delete the cache in iOS application development anyway
Even if I want to convert the contents of a data object to JSON in Java, there is a circular reference ...
I want you to put the story that the error was solved when you stabbed the charger in the corner of your head
If you use SQLite with VSCode, use the extension (how to see the binary file of sqlite3)
[rails] After option useful when you want to change the order of DB columns
If you want to know the options when configuring Ruby, see `RbConfig :: CONFIG ["configure_args "]`
What to do if you get a wrong number of arguments error in binding.pry
For those who want to use MySQL for the database in the environment construction of Rails6 ~.
If you make a mistake in the description location of Gem, delete Gemfile.lock once.
[Active Admin] I want to specify the scope of the collection to be displayed in select_box
[Rails] I want to display the link destination of link_to in a separate tab
[Java] How to omit the private constructor in Lombok
I want to embed any TraceId in the log
If you want to separate Spring Boot + Thymeleaf processing
If hash [: a] [: b] [: c] = 0 in Ruby, I want you to extend it recursively even if the key does not exist.
I can't input Japanese with VS code (Visual Studio Code) of Ubuntu 18.04.5! ?? If you want to download VS Code to Ubuntu, go to the official website! !!
Test the contents of an Excel file with JUnit
Understand the characteristics of Scala in 5 minutes (Introduction to Scala)
I want to know the answer of the rock-paper-scissors app
I want to display the name of the poster of the comment
If you want to use Mockito with Kotlin, use mockito-kotlin