From a6874e13b031a6ef918affcc0942a0a78f09590b Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 29 Dec 2023 12:10:26 +0100 Subject: [PATCH] Migrate ActorBehaviorTest to JUnit5 Eliminate the need for mockito-subclass by migrating to JUnit5 and correcting mocking configuration. Change-Id: I3d3a772abe71e0d0576474aa9f2b22cef7fbea0a Signed-off-by: Robert Varga --- opendaylight/md-sal/cds-access-client/pom.xml | 6 -- .../access/client/ActorBehaviorTest.java | 83 +++++++++---------- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/opendaylight/md-sal/cds-access-client/pom.xml b/opendaylight/md-sal/cds-access-client/pom.xml index 6542c57807..4dd0044710 100644 --- a/opendaylight/md-sal/cds-access-client/pom.xml +++ b/opendaylight/md-sal/cds-access-client/pom.xml @@ -51,12 +51,6 @@ true - - - org.mockito - mockito-subclass - test - com.typesafe config diff --git a/opendaylight/md-sal/cds-access-client/src/test/java/org/opendaylight/controller/cluster/access/client/ActorBehaviorTest.java b/opendaylight/md-sal/cds-access-client/src/test/java/org/opendaylight/controller/cluster/access/client/ActorBehaviorTest.java index 0b630e2da8..90ffd77a34 100644 --- a/opendaylight/md-sal/cds-access-client/src/test/java/org/opendaylight/controller/cluster/access/client/ActorBehaviorTest.java +++ b/opendaylight/md-sal/cds-access-client/src/test/java/org/opendaylight/controller/cluster/access/client/ActorBehaviorTest.java @@ -7,11 +7,11 @@ */ package org.opendaylight.controller.cluster.access.client; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import akka.actor.ActorRef; import akka.actor.ActorSystem; @@ -22,34 +22,50 @@ import akka.persistence.SnapshotMetadata; import akka.testkit.TestProbe; import akka.testkit.javadsl.TestKit; import com.typesafe.config.ConfigFactory; -import java.lang.reflect.Field; import java.util.Optional; import java.util.concurrent.TimeUnit; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier; import org.opendaylight.controller.cluster.access.concepts.FrontendIdentifier; import org.opendaylight.controller.cluster.access.concepts.FrontendType; import org.opendaylight.controller.cluster.access.concepts.MemberName; import scala.concurrent.duration.FiniteDuration; -public class ActorBehaviorTest { - +@ExtendWith(MockitoExtension.class) +class ActorBehaviorTest { private static final String MEMBER_1_FRONTEND_TYPE_1 = "member-1-frontend-type-1"; private static final FiniteDuration TIMEOUT = FiniteDuration.create(5, TimeUnit.SECONDS); + @Mock + private InternalCommand cmd; + @Mock(answer = Answers.CALLS_REAL_METHODS) + private ClientActorBehavior initialBehavior; + @Mock + private AbstractClientActorContext ctx; + private ActorSystem system; private TestProbe probe; - private ClientActorBehavior initialBehavior; private MockedSnapshotStore.SaveRequest saveRequest; private FrontendIdentifier id; private ActorRef mockedActor; - @Before - public void setUp() throws Exception { - initialBehavior = createInitialBehaviorMock(); + @BeforeEach + void beforeEach() throws Exception { + //persistenceId() in AbstractClientActorBehavior is final and can't be mocked + //use reflection to work around this + final var context = AbstractClientActorBehavior.class.getDeclaredField("context"); + context.setAccessible(true); + context.set(initialBehavior, ctx); + final var persistenceId = AbstractClientActorContext.class.getDeclaredField("persistenceId"); + persistenceId.setAccessible(true); + persistenceId.set(ctx, MEMBER_1_FRONTEND_TYPE_1); + system = ActorSystem.apply("system1"); final ActorRef storeRef = system.registerExtension(Persistence.lookup()).snapshotStoreFor(null, ConfigFactory.empty()); @@ -62,25 +78,23 @@ public class ActorBehaviorTest { saveRequest = handleRecovery(null); } - @After - public void tearDown() { + @AfterEach + void afterEach() { TestKit.shutdownActorSystem(system); } @Test - public void testInitialBehavior() { - final InternalCommand cmd = mock(InternalCommand.class); - when(cmd.execute(any())).thenReturn(initialBehavior); + void testInitialBehavior() { + doReturn(initialBehavior).when(cmd).execute(any()); mockedActor.tell(cmd, ActorRef.noSender()); verify(cmd, timeout(1000)).execute(initialBehavior); } @Test - public void testCommandStashing() { + void testCommandStashing() { system.stop(mockedActor); mockedActor = system.actorOf(MockedActor.props(id, initialBehavior)); - final InternalCommand cmd = mock(InternalCommand.class); - when(cmd.execute(any())).thenReturn(initialBehavior); + doReturn(initialBehavior).when(cmd).execute(any()); //send messages before recovery is completed mockedActor.tell(cmd, ActorRef.noSender()); mockedActor.tell(cmd, ActorRef.noSender()); @@ -91,16 +105,16 @@ public class ActorBehaviorTest { } @Test - public void testRecoveryAfterRestart() { + void testRecoveryAfterRestart() { system.stop(mockedActor); mockedActor = system.actorOf(MockedActor.props(id, initialBehavior)); final MockedSnapshotStore.SaveRequest newSaveRequest = handleRecovery(new SelectedSnapshot(saveRequest.getMetadata(), saveRequest.getSnapshot())); - Assert.assertEquals(MEMBER_1_FRONTEND_TYPE_1, newSaveRequest.getMetadata().persistenceId()); + assertEquals(MEMBER_1_FRONTEND_TYPE_1, newSaveRequest.getMetadata().persistenceId()); } @Test - public void testRecoveryAfterRestartFrontendIdMismatch() { + void testRecoveryAfterRestartFrontendIdMismatch() { system.stop(mockedActor); //start actor again mockedActor = system.actorOf(MockedActor.props(id, initialBehavior)); @@ -117,7 +131,7 @@ public class ActorBehaviorTest { } @Test - public void testRecoveryAfterRestartSaveSnapshotFail() { + void testRecoveryAfterRestartSaveSnapshotFail() { system.stop(mockedActor); mockedActor = system.actorOf(MockedActor.props(id, initialBehavior)); probe.watch(mockedActor); @@ -130,7 +144,7 @@ public class ActorBehaviorTest { } @Test - public void testRecoveryAfterRestartDeleteSnapshotsFail() { + void testRecoveryAfterRestartDeleteSnapshotsFail() { system.stop(mockedActor); mockedActor = system.actorOf(MockedActor.props(id, initialBehavior)); probe.watch(mockedActor); @@ -144,21 +158,6 @@ public class ActorBehaviorTest { probe.expectNoMessage(); } - @SuppressWarnings("unchecked") - private static ClientActorBehavior createInitialBehaviorMock() throws Exception { - final ClientActorBehavior initialBehavior = mock(ClientActorBehavior.class); - //persistenceId() in AbstractClientActorBehavior is final and can't be mocked - //use reflection to work around this - final Field context = AbstractClientActorBehavior.class.getDeclaredField("context"); - context.setAccessible(true); - final AbstractClientActorContext ctx = mock(AbstractClientActorContext.class); - context.set(initialBehavior, ctx); - final Field persistenceId = AbstractClientActorContext.class.getDeclaredField("persistenceId"); - persistenceId.setAccessible(true); - persistenceId.set(ctx, MEMBER_1_FRONTEND_TYPE_1); - return initialBehavior; - } - private MockedSnapshotStore.SaveRequest handleRecovery(final SelectedSnapshot savedState) { probe.expectMsgClass(MockedSnapshotStore.LoadRequest.class); //offer snapshot @@ -173,7 +172,6 @@ public class ActorBehaviorTest { } private static class MockedActor extends AbstractClientActor { - private final ClientActorBehavior initialBehavior; private final ClientActorConfig mockConfig = AccessClientUtil.newMockClientActorConfig(); @@ -196,5 +194,4 @@ public class ActorBehaviorTest { return mockConfig; } } - } -- 2.36.6