How to make Java unit tests (JUnit & Mockito & PowerMock)

It is a summary for myself. Describes how to create a Java unit test using the following library. --JUnit (Testing Framework) --Mockito (mock creation framework) --PowerMock (Mockito's extension framework)

Gradle settings

I used Gradle to download the necessary files (JUnit, Mockito, PowerMock). The contents of the configuration file are as follows.

build.gradle


apply plugin: 'java'

repositories {
    jcenter()
}

dependencies {
    testCompile 'junit:junit:4.12'
    testCompile "org.mockito:mockito-core:2.+"
    testCompile 'org.powermock:powermock-module-junit4:2.0.0-RC.4'
    testCompile 'org.powermock:powermock-api-mockito2:2.0.0-RC.4'
}

Tested class

This is the class to be tested. Consider using JUnit, Mockito, and PowerMock for this class.

Samole.java


public class Sample {
    private Sub sub;

    public Sample() {}

    public Sample(Sub sub) {
        this.sub = sub;
    }

    public String pubGet() {
        return "pubGet";
    }

    public String pubGet(String suffix) {
        return pubGet() + suffix;
    }

    public String pubGetSubValue() {
        return sub.getValue();
    }

    public String pubGetStaticValue() {
        return Static.getValue();
    }

    private String priGet() {
        return "priGet";
    }

    private String priGet(String suffix) {
        return priGet() + suffix;
    }

    public static class Sub {
        private String value;
        public Sub(String value) {
            this.value = value;
        }
        public String getValue() {
            return value;
        }
    }

    public static class Static {
        public static String getValue() {
            return "Static value";
        }
    }
}

JUnit only test class

When using only JUnit.

SampleTest.java


import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.Method;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;

public class SampleTest {
    private Sample instance;
    @Before
    public void init() {
        this.instance = new Sample();
    }
    @Test
    public void pubGet() {
        //Public method testing
        String actual = instance.pubGet();
        assertThat(actual, is("pubGet"));
    }
    @Test
    public void priGet() throws Exception {
        //Private method test (no arguments)
        Method method = Sample.class.getDeclaredMethod("priGet");
        method.setAccessible(true);

        String actual = (String) method.invoke(instance);
        assertThat(actual, is("priGet"));
    }
    @Test
    public void priGet_withArg() throws Exception {
        //Private method test (with arguments)
        Method method = Sample.class.getDeclaredMethod("priGet", String.class);
        method.setAccessible(true);

        String actual = (String) method.invoke(instance, "Suffix");
        assertThat(actual, is("priGetSuffix"));
    }
    @Test
    public void pubGetSubValue() {
        Sample instance = new Sample(new Sample.Sub("test"));

        String actual = instance.pubGetSubValue();
        assertThat(actual, is("test"));
    }

}

Test class using JUnit & Mockito

When Mockito is added. You can rewrite the contents of the method using a mock.

SampleForMockitoTest.java


import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;

import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class SampleForMockitoTest {
    @Mock
    private Sample mock;
    @Spy
    private Sample spy;
    @Before
    public void init() {
        // @Initialize the mock object of the Mock annotation
        MockitoAnnotations.initMocks(this);
    }
    @Test
    public void pubGetSubValue() {
        //When not using a mock
        Sample instance = new Sample(new Sample.Sub("test"));

        String actual = instance.pubGetSubValue();
        assertThat(actual, is("test"));
    }
    @Test
    public void pubGetSubValue_withMockito() {
        //Returns the value of the stub when using a mock
        Sample.Sub mock = mock(Sample.Sub.class);
        when(mock.getValue()).thenReturn("mock value");
        Sample instance = new Sample(mock);

        String actual = instance.pubGetSubValue();
        assertThat(actual, is("mock value"));
    }

    @Test
    public void pubGetSubValue_withMockitoMock() {
        // mock()Will be the default value (null) if stub is not implemented
        String actual1 = mock.pubGet();
        assertThat(actual1, is(nullValue()));

        // mock()Returns the value of a stub when implementing a stub
        when(mock.pubGet()).thenReturn("mock value");
        String actual2 = mock.pubGet();
        assertThat(actual2, is("mock value"));
    }

    @Test
    public void pubGetSubValue_withMockitoSpy() {
        // spy()Returns the actual value without implementing a stub
        String actual1 = spy.pubGet();
        assertThat(actual1, is("pubGet"));

        // spy()Returns the value of a stub when implementing a stub
        when(spy.pubGet()).thenReturn("mock value");
        String actual2 = spy.pubGet();
        assertThat(actual2, is("mock value"));
    }
    @Test
    public void pubGetSubValue_withMockitoAnswer() {
        // mock()Returns the value of a stub when implementing a stub
        //Answer allows you to use method arguments for stubs
        when(mock.pubGet(anyString())).thenAnswer(invocation -> {
            String arg1 = (String) invocation.getArguments()[0];
            return "mock value " + arg1;
        });
        String actual = mock.pubGet("suffix");
        assertThat(actual, is("mock value suffix"));
    }
}

Test class with JUnit & Mockito & PowerMock

When PowerMock is added. You can rewrite the contents of the static method.

SamleForPowerMockTest.java


import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Sample.Static.class})
public class SamleForPowerMockTest {
    private Sample instance;
    @Before
    public void init() {
        instance = new Sample();
    }
    @Test
    public void pubGetWithStatic() {
        //Test the value of a static method
        String actual = instance.pubGetStaticValue();
        assertThat(actual, is("Static value"));
    }
    @Test
    public void pubGetWithStatic_withPowerMock() {
        // mockStatic()Static method returns stub value in
        PowerMockito.mockStatic(Sample.Static.class);
        //If you want the original behavior other than the desired method, use PowerMockito instead.spy()use
        // PowerMockito.spy(Sample.Static.class); 
        PowerMockito.when(Sample.Static.getValue()).thenReturn("PowerMockito value");

        String actual = instance.pubGetStaticValue();
        assertThat(actual, is("PowerMockito value"));
    }
}

Summary

PowerMock allows for powerful rewriting. However, if you rely too much on PowerMock, you lose sight of its original purpose (extensible implementation). I also felt the danger of being a test that only gained coverage, so it seems better to think about where to use it.

Remarks

I referred to Use of Mockito and PowerMock properly.

Recommended Posts

How to make Java unit tests (JUnit & Mockito & PowerMock)
Java --How to make JTable
Java unit tests with Mockito
How to make a Java container
How to make a Java array
How to make a Java calendar Summary
How to make a Discord bot (Java)
[Java] How to test for null with JUnit
[Rails] How to implement unit tests for models
[Java] How to make multiple for loops single
How to make shaded-jar
How to write Mockito
How to use JUnit 5
[Java] How to use Map
How to lower java version
[Java] How to use Map
How to uninstall Java 8 (Mac)
How to use java Optional
How to use JUnit (beginner)
How to minimize Java images
How to write java comments
How to use java class
[Java] How to use Optional ②
[Java] How to use removeAll ()
[Java] How to display Wingdings
[Java] How to use string.format
How to use Java Map
How to set Java constants
How to write Junit 5 organized
How to use Java variables
How to convert Java radix
[Rails] How to make seed
[Java] How to implement multithreading
[Java] How to use Optional ①
How to migrate from JUnit4 to JUnit5
How to initialize Java array
[Creating] How to use JUnit
Use Spring Test + Mockito + JUnit 4 for Spring Boot + Spring Retry unit tests
How to study Java Silver SE 8
How to use Java HttpClient (Get)
How to unit test Spring AOP
How to run JUnit in Eclipse
Studying Java # 6 (How to write blocks)
[Java] How to update Java on Windows
How to use Java HttpClient (Post)
[Java] How to use join method
How to make a JDBC driver
How to learn JAVA in 7 days
How to make Wowza Streaming Engine JAVA API custom module (preparation)
[Processing × Java] How to use variables
[Java] How to create a folder
How to decompile java class files
[Java] How to use LinkedHashMap class
[JavaFX] [Java8] How to use GridPane
How to write Java variable declaration
Introducing Java tips GreenMail to Junit5
How to make a splash screen
How to make a Jenkins plugin
How to use class methods [Java]
[Java] How to use List [ArrayList]
How to use classes in Java?