From ab9c00799216ec6eab11dec78ad27b8afa7ea3c7 Mon Sep 17 00:00:00 2001 From: Dean Brettle Date: Sat, 20 Apr 2024 19:18:51 -0700 Subject: [PATCH] Use stubOnly() mocks instead of periodic calls to clearInvocations(). --- .../org/carlmontrobotics/lib199/Mocks.java | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/carlmontrobotics/lib199/Mocks.java b/src/main/java/org/carlmontrobotics/lib199/Mocks.java index f20db5d8..2feec122 100644 --- a/src/main/java/org/carlmontrobotics/lib199/Mocks.java +++ b/src/main/java/org/carlmontrobotics/lib199/Mocks.java @@ -1,15 +1,11 @@ package org.carlmontrobotics.lib199; -import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.Consumer; -import java.util.function.Predicate; import java.util.stream.Collectors; import org.mockito.MockSettings; @@ -20,25 +16,6 @@ public final class Mocks { - private static final CopyOnWriteArrayList> MOCKS = new CopyOnWriteArrayList<>(); - private static final Predicate> IS_REFERENCE_CLEARED = reference -> reference.get() == null; - private static final Consumer> CLEAR_INVOCATIONS_ON_REFERENCED_MOCK = reference -> Mockito.clearInvocations(reference.get()); - private static final Predicate> CLEAR_INVOCATIONS_ON_REFERENCED_MOCK_IF_REFERENCE_NOT_CLEARED = reference -> { - if(IS_REFERENCE_CLEARED.test(reference)) return true; - CLEAR_INVOCATIONS_ON_REFERENCED_MOCK.accept(reference); - return false; - }; - - static { - // Use a single predicate so that clearing references and invocations is an atomic operation - // Otherwise, we could (rarely) run into: - // 1) Mock is added - // 2) Garbage collected references are removed - // 3) Mock is garbage collected - // 4) Mock invocations are cleared -> throws NullPointerException - Lib199Subsystem.registerAsyncPeriodic(() -> MOCKS.removeIf(CLEAR_INVOCATIONS_ON_REFERENCED_MOCK_IF_REFERENCE_NOT_CLEARED)); - } - /** * Attempts to create an instance of a class in which some or all of the classes methods are replaced with a mocked implementation * @param the class type which will be mocked @@ -103,6 +80,7 @@ public static T createMock(Class classToMock, U implClass, Answer(methods, implClass, defaultAnswer)); + settings = settings.stubOnly(); // Because recording invocations would cause memory usage to grow without bound T mock = mock(classToMock, settings); return mock; } @@ -157,15 +135,14 @@ public static T mock(Class classToMock, MockSettings mockSettings) { } /** - * Registers a Mockito mock and periodically calls {@link Mockito#clearInvocations(Object...)} on it to prevent memory leaks + * No longer does anything. * * @param The type of the mock * @param t The mock * @return The mock */ + @Deprecated public static T reportMock(T t) { - // Wrap in a WeakReference to prevent memory leaks on objects with no more references - if(Mockito.mockingDetails(t).isMock()) MOCKS.add(new WeakReference(t)); return t; }