Skip to content

Commit d365ddb

Browse files
committed
fix possible edge-case
If a mock's reference was cleared between IS_REFERENCE_CLEARED.test and CLEAR_INVOCATIONS_ON_REFERENCED_MOCK.accept, the latter would throw an exception. By storing the referenced value in a member variable throughout both operations, the value cannot be null. This change should be tested before being merged into master
1 parent f380f1e commit d365ddb

1 file changed

Lines changed: 6 additions & 10 deletions

File tree

  • src/main/java/org/carlmontrobotics/lib199

src/main/java/org/carlmontrobotics/lib199/Mocks.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
import java.util.Arrays;
99
import java.util.HashMap;
1010
import java.util.concurrent.CopyOnWriteArrayList;
11-
import java.util.function.Consumer;
12-
import java.util.function.Predicate;
1311
import java.util.stream.Collectors;
1412

1513
import org.mockito.MockSettings;
@@ -21,13 +19,6 @@
2119
public final class Mocks {
2220

2321
private static final CopyOnWriteArrayList<WeakReference<Object>> MOCKS = new CopyOnWriteArrayList<>();
24-
private static final Predicate<WeakReference<?>> IS_REFERENCE_CLEARED = reference -> reference.get() == null;
25-
private static final Consumer<WeakReference<Object>> CLEAR_INVOCATIONS_ON_REFERENCED_MOCK = reference -> Mockito.clearInvocations(reference.get());
26-
private static final Predicate<WeakReference<Object>> CLEAR_INVOCATIONS_ON_REFERENCED_MOCK_IF_REFERENCE_NOT_CLEARED = reference -> {
27-
if(IS_REFERENCE_CLEARED.test(reference)) return true;
28-
CLEAR_INVOCATIONS_ON_REFERENCED_MOCK.accept(reference);
29-
return false;
30-
};
3122

3223
static {
3324
// Use a single predicate so that clearing references and invocations is an atomic operation
@@ -36,7 +27,12 @@ public final class Mocks {
3627
// 2) Garbage collected references are removed
3728
// 3) Mock is garbage collected
3829
// 4) Mock invocations are cleared -> throws NullPointerException
39-
Lib199Subsystem.registerAsyncPeriodic(() -> MOCKS.removeIf(CLEAR_INVOCATIONS_ON_REFERENCED_MOCK_IF_REFERENCE_NOT_CLEARED));
30+
Lib199Subsystem.registerAsyncPeriodic(() -> MOCKS.removeIf(reference -> {
31+
Object mock = reference.get();
32+
if(mock == null) return true;
33+
Mockito.clearInvocations(mock);
34+
return false;
35+
}));
4036
}
4137

4238
/**

0 commit comments

Comments
 (0)