Testing in Java with JUnit 5 and Mockito

Lesson learned re. testing in Java with Mockito and JUnit5

FYI for anyone using the Java SDK that wants to unit test with JUnit 5 instead of version 4, I was able to adapt the HelloWorldWorkflowTest to run with the following:

build.gradle:

dependencies {
    implementation 'io.temporal:temporal-sdk:1.0.6'

    // Testing dependencies
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
    testImplementation 'org.mockito:mockito-core:3.9.0'
    testImplementation 'io.temporal:temporal-testing:1.0.6'
    testImplementation 'io.temporal:temporal-testing-junit5:1.0.6'
}

HelloWorldWorkflowTest.java:

package helloworldapp;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.withSettings;
import static org.mockito.Mockito.verify;

import io.temporal.testing.TestWorkflowExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

class HelloWorldWorkflowTest {

    private static final Format format = mock(Format.class, withSettings().withoutAnnotations());

    @RegisterExtension
    public static final TestWorkflowExtension workflowExtension =
                    TestWorkflowExtension.newBuilder()
                    .setWorkflowTypes(HelloWorldWorkflowImpl.class)
                    .setActivityImplementations(format)
                    .build();

    @Test
    void testGetGreeting(HelloWorldWorkflow workflow) {
        workflow.getGreeting("test");
        verify(format).composeGreeting("test");
    }
}

When mocking Activity interfaces using Mockito you need to tell it not to copy over the annotations, eg:

Mockito.mock(Format.class, withSettings().withoutAnnotations())

Otherwise you’ll get some nasty errors that look like this:

java.lang.IllegalArgumentException: Found @ActivityMethod annotation on "public java.lang.String helloworldapp.Format$MockitoMock$255547570.composeGreeting(java.lang.String)" This annotation can be used only on the interface method it implements.

This may be common knowledge but I struggled for an hour or so to get it to work, so I hope this is helpful for someone.

2 Likes