This is an automated email from the ASF dual-hosted git repository. solomax pushed a commit to branch injected-fields in repository https://gitbox.apache.org/repos/asf/openmeetings.git
commit 5fe24e4ea4045af308f3668dc52096b68e6158cc Author: Maxim Solodovnik <solomax...@gmail.com> AuthorDate: Tue Mar 16 22:17:42 2021 +0700 [OPENMEETINGS-2588] non-beans are injected, tests are green --- openmeetings-core/pom.xml | 5 ++ .../org/apache/openmeetings/core/remote/KRoom.java | 59 ++++++++++++---------- .../apache/openmeetings/core/remote/KStream.java | 33 ++++++++---- .../openmeetings/core/remote/KTestStream.java | 16 ++++-- .../openmeetings/core/remote/KurentoHandler.java | 24 +-------- .../openmeetings/core/remote/StreamProcessor.java | 2 +- .../core/remote/StreamProcessorActions.java | 2 +- .../core/remote/TestStreamProcessor.java | 2 +- .../openmeetings/core/remote/BaseMockedTest.java | 50 ++++++++++++++++++ 9 files changed, 125 insertions(+), 68 deletions(-) diff --git a/openmeetings-core/pom.xml b/openmeetings-core/pom.xml index dfb1100..7b61a40 100644 --- a/openmeetings-core/pom.xml +++ b/openmeetings-core/pom.xml @@ -77,6 +77,11 @@ <version>${wicket.version}</version> </dependency> <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-ioc</artifactId> + <version>${wicket.version}</version> + </dependency> + <dependency> <groupId>org.apache.directory.api</groupId> <artifactId>api-all</artifactId> <version>${api-all.version}</version> diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java index 3de644f..04c9a08 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java @@ -27,10 +27,12 @@ import java.util.Date; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; +import javax.inject.Inject; + import org.apache.commons.lang3.time.FastDateFormat; import org.apache.openmeetings.IApplication; import org.apache.openmeetings.core.util.WebSocketHelper; -import org.apache.openmeetings.db.dao.record.RecordingChunkDao; +import org.apache.openmeetings.db.dao.record.RecordingDao; import org.apache.openmeetings.db.entity.basic.Client; import org.apache.openmeetings.db.entity.basic.Client.Activity; import org.apache.openmeetings.db.entity.basic.Client.StreamDesc; @@ -43,6 +45,7 @@ import org.apache.openmeetings.db.manager.IClientManager; import org.apache.openmeetings.db.util.FormatHelper; import org.apache.openmeetings.db.util.ws.RoomMessage; import org.apache.openmeetings.db.util.ws.TextRoomMessage; +import org.apache.wicket.injection.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,8 +58,15 @@ import com.github.openjson.JSONObject; public class KRoom { private static final Logger log = LoggerFactory.getLogger(KRoom.class); - private final StreamProcessor processor; - private final RecordingChunkDao chunkDao; + @Inject + private KurentoHandler kHandler; + @Inject + private StreamProcessor processor; + @Inject + private RecordingDao recDao; + @Inject + private IClientManager cm; + private final Room room; private final AtomicBoolean recordingStarted = new AtomicBoolean(false); private final AtomicBoolean sharingStarted = new AtomicBoolean(false); @@ -65,10 +75,9 @@ public class KRoom { private JSONObject recordingUser = new JSONObject(); private JSONObject sharingUser = new JSONObject(); - public KRoom(KurentoHandler handler, Room r) { - this.processor = handler.getStreamProcessor(); - this.chunkDao = handler.getChunkDao(); + public KRoom(Room r) { this.room = r; + Injector.get().inject(this); log.info("ROOM {} has been created", room.getId()); } @@ -80,13 +89,9 @@ public class KRoom { return recordingId; } - public RecordingChunkDao getChunkDao() { - return chunkDao; - } - - public KStream join(final StreamDesc sd, KurentoHandler kHandler) { + public KStream join(final StreamDesc sd) { log.info("ROOM {}: join client {}, stream: {}", room.getId(), sd.getClient(), sd.getUid()); - final KStream stream = new KStream(sd, this, kHandler); + final KStream stream = new KStream(sd, this); processor.addStream(stream); return stream; } @@ -144,11 +149,11 @@ public class KRoom { Optional<StreamDesc> osd = c.getScreenStream(); if (osd.isPresent()) { osd.get().addActivity(Activity.RECORD); - processor.getClientManager().update(c); + cm.update(c); rec.setWidth(osd.get().getWidth()); rec.setHeight(osd.get().getHeight()); } - rec = processor.getRecordingDao().update(rec); + rec = recDao.update(rec); // Receive recordingId recordingId = rec.getId(); processor.getByRoom(room.getId()).forEach(KStream::startRecord); @@ -163,9 +168,9 @@ public class KRoom { if (recordingStarted.compareAndSet(true, false)) { log.debug("##REC:: recording in room {} is stopping {} ::", room.getId(), recordingId); processor.getByRoom(room.getId()).forEach(KStream::stopRecord); - Recording rec = processor.getRecordingDao().get(recordingId); + Recording rec = recDao.get(recordingId); rec.setRecordEnd(new Date()); - rec = processor.getRecordingDao().update(rec); + rec = recDao.update(rec); recordingUser = new JSONObject(); recordingId = null; @@ -178,8 +183,8 @@ public class KRoom { Optional<StreamDesc> osd = c.getScreenStream(); if (osd.isPresent()) { osd.get().removeActivity(Activity.RECORD); - processor.getClientManager().update(c); - processor.getHandler().sendShareUpdated(osd.get()); + cm.update(c); + kHandler.sendShareUpdated(osd.get()); } } // Send notification to all users that the recording has been started @@ -203,29 +208,28 @@ public class KRoom { return new JSONObject(sharingUser.toString()); } - public void startSharing(StreamProcessor processor, IClientManager cm, Client c, Optional<StreamDesc> osd, JSONObject msg, Activity a) { + public void startSharing(Client c, Optional<StreamDesc> osd, JSONObject msg, Activity a) { StreamDesc sd; - KurentoHandler h = processor.getHandler(); if (sharingStarted.compareAndSet(false, true)) { sharingUser.put("sid", c.getSid()); sd = c.addStream(StreamType.SCREEN, a); cm.update(c); log.debug("Stream.UID {}: sharing has been started, activity: {}", sd.getUid(), a); - h.sendClient(sd.getSid(), newKurentoMsg() + kHandler.sendClient(sd.getSid(), newKurentoMsg() .put("id", "broadcast") .put("stream", sd.toJson() .put("shareType", msg.getString("shareType")) .put("fps", msg.getString("fps"))) - .put(PARAM_ICE, h.getTurnServers(c))); + .put(PARAM_ICE, kHandler.getTurnServers(c))); } else if (osd.isPresent() && !osd.get().hasActivity(a)) { sd = osd.get(); sd.addActivity(a); cm.update(c); - h.sendShareUpdated(sd); + kHandler.sendShareUpdated(sd); WebSocketHelper.sendRoom(new TextRoomMessage(c.getRoomId(), c, RoomMessage.Type.RIGHT_UPDATED, c.getUid())); WebSocketHelper.sendRoomOthers(room.getId(), c.getUid(), newKurentoMsg() .put("id", "newStream") - .put(PARAM_ICE, processor.getHandler().getTurnServers(c)) + .put(PARAM_ICE, kHandler.getTurnServers(c)) .put("stream", sd.toJson())); } } @@ -245,17 +249,16 @@ public class KRoom { if (count != sipCount) { processor.getByRoom(room.getId()).forEach(stream -> stream.addSipProcessor(count)); if (sipCount == 0) { - processor.getClientManager() - .streamByRoom(room.getId()) + cm.streamByRoom(room.getId()) .filter(Client::isSip) .findAny() .ifPresent(c -> { StreamDesc sd = c.addStream(StreamType.WEBCAM, Activity.AUDIO); sd.setWidth(120).setHeight(90); c.restoreActivities(sd); - KStream stream = join(sd, processor.getHandler()); + KStream stream = join(sd); stream.startBroadcast(sd, "", () -> {}); - processor.getClientManager().update(c); + cm.update(c); }); } sipCount = count; diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java index 56f2a58..f461c6d 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java @@ -43,9 +43,13 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import javax.inject.Inject; + import org.apache.openmeetings.core.sip.ISipCallbacks; +import org.apache.openmeetings.core.sip.SipManager; import org.apache.openmeetings.core.sip.SipStackProcessor; import org.apache.openmeetings.core.util.WebSocketHelper; +import org.apache.openmeetings.db.dao.record.RecordingChunkDao; import org.apache.openmeetings.db.entity.basic.Client; import org.apache.openmeetings.db.entity.basic.Client.Activity; import org.apache.openmeetings.db.entity.basic.Client.StreamDesc; @@ -54,6 +58,7 @@ import org.apache.openmeetings.db.entity.record.RecordingChunk.Type; import org.apache.openmeetings.db.util.ws.RoomMessage; import org.apache.openmeetings.db.util.ws.TextRoomMessage; import org.apache.openmeetings.util.OmFileHelper; +import org.apache.wicket.injection.Injector; import org.kurento.client.BaseRtpEndpoint; import org.kurento.client.Continuation; import org.kurento.client.IceCandidate; @@ -75,7 +80,15 @@ import com.github.openjson.JSONObject; public class KStream extends AbstractStream implements ISipCallbacks { private static final Logger log = LoggerFactory.getLogger(KStream.class); - private final KurentoHandler kHandler; + @Inject + private KurentoHandler kHandler; + @Inject + private StreamProcessor processor; + @Inject + private RecordingChunkDao chunkDao; + @Inject + private SipManager sipManager; + private final KRoom kRoom; private final Date connectedSince; private final StreamType streamType; @@ -96,12 +109,12 @@ public class KStream extends AbstractStream implements ISipCallbacks { private boolean hasScreen; private boolean sipClient; - public KStream(final StreamDesc sd, KRoom kRoom, KurentoHandler kHandler) { + public KStream(final StreamDesc sd, KRoom kRoom) { super(sd.getSid(), sd.getUid()); this.kRoom = kRoom; streamType = sd.getType(); this.connectedSince = new Date(); - this.kHandler = kHandler; + Injector.get().inject(this); //TODO Min/MaxVideoSendBandwidth //TODO Min/Max Audio/Video RecvBandwidth } @@ -189,7 +202,7 @@ public class KStream extends AbstractStream implements ISipCallbacks { flowoutFuture = Optional.of(new CompletableFuture<>().completeAsync(() -> { log.warn("KStream will be dropped {}, sid {}, uid {}", sd, sid, uid); if (StreamType.SCREEN == streamType) { - kHandler.getStreamProcessor().doStopSharing(sid, uid); + processor.doStopSharing(sid, uid); } stopBroadcast(); return null; @@ -275,7 +288,7 @@ public class KStream extends AbstractStream implements ISipCallbacks { listeners.put(uid, listener); log.debug("PARTICIPANT {}: obtained endpoint for {}", uid, this.uid); - Client cur = kHandler.getStreamProcessor().getBySid(this.sid); + Client cur = processor.getBySid(this.sid); if (cur == null) { log.warn("Client for endpoint dooesn't exists"); } else { @@ -338,9 +351,9 @@ public class KStream extends AbstractStream implements ISipCallbacks { recorder = createRecorderEndpoint(pipeline, getRecUri(getRecordingChunk(getRoomId(), chunkUid)), profile); setTags(recorder, uid); - recorder.addRecordingListener(evt -> chunkId = kRoom.getChunkDao().start(kRoom.getRecordingId(), type, chunkUid, sid)); + recorder.addRecordingListener(evt -> chunkId = chunkDao.start(kRoom.getRecordingId(), type, chunkUid, sid)); recorder.addStoppedListener(evt -> { - kRoom.getChunkDao().stop(chunkId); + chunkDao.stop(chunkId); chunkId = null; }); switch (profile) { @@ -459,7 +472,7 @@ public class KStream extends AbstractStream implements ISipCallbacks { private void doRemove(boolean remove) { if (remove) { - kHandler.getStreamProcessor().release(this, false); + processor.release(this, false); } } @@ -606,7 +619,7 @@ public class KStream extends AbstractStream implements ISipCallbacks { if (count > 0) { if (sipProcessor.isEmpty()) { try { - sipProcessor = kHandler.getSipManager().createSipStackProcessor( + sipProcessor = sipManager.createSipStackProcessor( randomUUID().toString() , kRoom.getRoom() , this); @@ -644,7 +657,7 @@ public class KStream extends AbstractStream implements ISipCallbacks { answerConsumer.accept(answer); log.debug(answer); if (sipClient) { - StreamDesc sd = kHandler.getStreamProcessor().getBySid(sid).getStream(uid); + StreamDesc sd = processor.getBySid(sid).getStream(uid); try { outgoingMedia = rtpEndpoint; internalStartBroadcast(sd, sdp); diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java index 741c1f6..57111ed 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java @@ -36,9 +36,12 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import javax.inject.Inject; + import org.apache.openmeetings.core.util.WebSocketHelper; import org.apache.openmeetings.db.entity.basic.IWsClient; import org.apache.openmeetings.util.OmFileHelper; +import org.apache.wicket.injection.Injector; import org.kurento.client.Continuation; import org.kurento.client.IceCandidate; import org.kurento.client.MediaPipeline; @@ -55,7 +58,12 @@ import com.github.openjson.JSONObject; public class KTestStream extends AbstractStream { private static final Logger log = LoggerFactory.getLogger(KTestStream.class); private static final Map<String, String> TAGS = Map.of(TAG_MODE, MODE_TEST, TAG_ROOM, MODE_TEST); - private final KurentoHandler kHandler; + + @Inject + private KurentoHandler kHandler; + @Inject + private TestStreamProcessor processor; + private MediaPipeline pipeline; private WebRtcEndpoint webRtcEndpoint; private PlayerEndpoint player; @@ -65,9 +73,9 @@ public class KTestStream extends AbstractStream { private ScheduledFuture<?> recHandle; private int recTime; - public KTestStream(IWsClient c, JSONObject msg, KurentoHandler kHandler) { + public KTestStream(IWsClient c, JSONObject msg) { super(null, c.getUid()); - this.kHandler = kHandler; + Injector.get().inject(this); createPipeline(() -> startTestRecording(c, msg)); } @@ -251,7 +259,7 @@ public class KTestStream extends AbstractStream { releasePlayer(); releaseRecorder(); if (remove) { - kHandler.getTestProcessor().release(this, true); + processor.release(this, true); } } } diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java index 1e8ebb4..a301dce 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java @@ -41,9 +41,7 @@ import javax.annotation.PreDestroy; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import org.apache.openmeetings.core.sip.SipManager; import org.apache.openmeetings.core.util.WebSocketHelper; -import org.apache.openmeetings.db.dao.record.RecordingChunkDao; import org.apache.openmeetings.db.dao.room.RoomDao; import org.apache.openmeetings.db.entity.basic.Client; import org.apache.openmeetings.db.entity.basic.Client.Activity; @@ -125,13 +123,9 @@ public class KurentoHandler { @Autowired private RoomDao roomDao; @Autowired - private RecordingChunkDao chunkDao; - @Autowired private TestStreamProcessor testProcessor; @Autowired private StreamProcessor streamProcessor; - @Autowired - private SipManager sipManager; boolean isConnected() { boolean connctd = connected.get() && client != null && !client.isClosed(); @@ -309,7 +303,7 @@ public class KurentoHandler { return rooms.computeIfAbsent(roomId, k -> { log.debug("Room {} does not exist. Will create now!", roomId); Room r = roomDao.get(roomId); - return new KRoom(this, r); + return new KRoom(r); }); } @@ -397,22 +391,6 @@ public class KurentoHandler { return kuid; } - public TestStreamProcessor getTestProcessor() { - return testProcessor; - } - - StreamProcessor getStreamProcessor() { - return streamProcessor; - } - - SipManager getSipManager() { - return sipManager; - } - - RecordingChunkDao getChunkDao() { - return chunkDao; - } - static int getFlowoutTimeout() { return flowoutTimeout; } diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java index 3771c0c..d99edb9 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java @@ -322,7 +322,7 @@ public class StreamProcessor implements IStreamProcessor { private void startSharing(Client c, Optional<StreamDesc> osd, JSONObject msg, Activity a) { if (kHandler.isConnected() && c.getRoomId() != null) { - kHandler.getRoom(c.getRoomId()).startSharing(this, cm, c, osd, msg, a); + kHandler.getRoom(c.getRoomId()).startSharing(c, osd, msg, a); } } diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java index 8608485..b80a290 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessorActions.java @@ -107,7 +107,7 @@ public class StreamProcessorActions { try { if (sender == null) { KRoom room = kHandler.getRoom(c.getRoomId()); - sender = room.join(sd, kHandler); + sender = room.join(sd); } if (msg.has("width")) { sd.setWidth(msg.getInt("width")).setHeight(msg.getInt("height")); diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java index 499d772..3bd7bde 100644 --- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java +++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/TestStreamProcessor.java @@ -56,7 +56,7 @@ class TestStreamProcessor implements IStreamProcessor { if (user != null) { user.release(); } - user = new KTestStream(c, msg, kHandler); + user = new KTestStream(c, msg); streamByUid.put(c.getUid(), user); break; case "iceCandidate": diff --git a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java index 4d94aa0..86f0211 100644 --- a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java +++ b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java @@ -22,11 +22,18 @@ package org.apache.openmeetings.core.remote; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.withSettings; +import static org.mockito.internal.util.collections.Sets.newMockSafeHashSet; +import java.lang.reflect.Field; import java.util.Locale; +import java.util.Set; + +import javax.inject.Inject; import org.apache.openmeetings.IApplication; import org.apache.openmeetings.core.util.WebSocketHelper; @@ -34,6 +41,7 @@ import org.apache.openmeetings.db.dao.label.LabelDao; import org.apache.openmeetings.db.entity.basic.IWsClient; import org.apache.openmeetings.db.entity.label.OmLanguage; import org.apache.openmeetings.db.util.ApplicationHelper; +import org.apache.wicket.injection.Injector; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.kurento.client.KurentoClient; @@ -49,14 +57,18 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Spy; +import org.mockito.internal.configuration.injection.scanner.MockScanner; import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.stubbing.Answer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.github.openjson.JSONObject; @ExtendWith(MockitoExtension.class) public class BaseMockedTest { + private static final Logger log = LoggerFactory.getLogger(BaseMockedTest.class); @Mock protected RomManager romManager; @Mock @@ -90,8 +102,12 @@ public class BaseMockedTest { MockedStatic<WebSocketHelper> wsHelperMock = mockStatic(WebSocketHelper.class); MockedStatic<LabelDao> labelMock = mockStatic(LabelDao.class); MockedStatic<ApplicationHelper> appHelpMock = mockStatic(ApplicationHelper.class); + MockedStatic<Injector> injectMock = mockStatic(Injector.class) ) { + Set<Object> mocks = newMockSafeHashSet(); + new MockScanner(this, BaseMockedTest.class).addPreparedMocks(mocks); + new MockScanner(this, this.getClass()).addPreparedMocks(mocks); wsHelperMock.when(() -> WebSocketHelper.sendClient(any(IWsClient.class), any(JSONObject.class))).thenAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { @@ -104,7 +120,41 @@ public class BaseMockedTest { labelMock.when(() -> LabelDao.getLanguage(any(Long.class))).thenReturn(new OmLanguage(1L, Locale.ENGLISH)); appHelpMock.when(() -> ApplicationHelper.ensureApplication(any(Long.class))).thenReturn(mock(IApplication.class)); + Injector injector = mock(Injector.class, withSettings().lenient()); + doAnswer(new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + Object o = invocation.getArgument(0); + if (forInjection(o)) { + inject(o, mocks); + } + return null; + } + }).when(injector).inject(any()); + injectMock.when(() -> Injector.get()).thenReturn(injector); task.run(); } } + + private boolean forInjection(Object o) { + return o instanceof KRoom || o instanceof KStream || o instanceof KTestStream; + } + + private void inject(Object o, Set<Object> mocks) { + for (Field f : o.getClass().getDeclaredFields()) { + if (f.isAnnotationPresent(Inject.class)) { + mocks.stream() + .filter(mock -> f.getType().isAssignableFrom(mock.getClass())) + .findAny() + .ifPresent(mock -> { + try { + f.setAccessible(true); + f.set(o, mock); + } catch (Exception e) { + log.error("Fail to set mock {} {}", f, mock); + } + }); + } + } + } }