From 50457b3827caeb21705ffc44000d696558b9dabb Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Sat, 25 Mar 2023 11:38:14 +0100 Subject: [PATCH] Fixes 2947: correct visibility check to respect nestmates where subclasses can invoke private constructors if they are nested classes. --- .../creation/bytebuddy/MockMethodAdvice.java | 12 +++---- .../InlineDelegateByteBuddyMockMakerTest.java | 35 +++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java index 6074eef038..9945a02278 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java @@ -4,11 +4,6 @@ */ package org.mockito.internal.creation.bytebuddy; -import static net.bytebuddy.matcher.ElementMatchers.isConstructor; -import static net.bytebuddy.matcher.ElementMatchers.isPrivate; -import static net.bytebuddy.matcher.ElementMatchers.isStatic; -import static net.bytebuddy.matcher.ElementMatchers.not; - import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; @@ -61,6 +56,11 @@ import org.mockito.internal.util.concurrent.WeakConcurrentMap; import org.mockito.plugins.MemberAccessor; +import static net.bytebuddy.matcher.ElementMatchers.isAccessibleTo; +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; +import static net.bytebuddy.matcher.ElementMatchers.isStatic; +import static net.bytebuddy.matcher.ElementMatchers.not; + public class MockMethodAdvice extends MockMethodDispatcher { private final WeakConcurrentMap interceptors; @@ -398,7 +398,7 @@ public MethodVisitor wrap( .getSuperClass() .asErasure() .getDeclaredMethods() - .filter(isConstructor().and(not(isPrivate()))); + .filter(isConstructor().and(isAccessibleTo(instrumentedType))); int arguments = Integer.MAX_VALUE; boolean packagePrivate = true; MethodDescription.InDefinedShape current = null; diff --git a/src/test/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMakerTest.java b/src/test/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMakerTest.java index 3d42f3a377..89aa415a96 100644 --- a/src/test/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMakerTest.java +++ b/src/test/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMakerTest.java @@ -80,6 +80,22 @@ public void should_create_mock_from_final_spy() throws Exception { }); } + @Test + public void should_create_mock_from_accessible_inner_spy() throws Exception { + MockCreationSettings settings = settingsFor(Outer.Inner.class); + Optional proxy = + mockMaker.createSpy( + settings, + new MockHandlerImpl<>(settings), + new Outer.Inner(new Object(), new Object())); + assertThat(proxy) + .hasValueSatisfying( + spy -> { + assertThat(spy.p1).isNotNull(); + assertThat(spy.p2).isNotNull(); + }); + } + @Test public void should_create_mock_from_non_constructable_class() throws Exception { MockCreationSettings settings = @@ -646,4 +662,23 @@ void internalThrowException(int test) throws IOException { } } } + + static class Outer { + + final Object p1; + + private Outer(final Object p1) { + this.p1 = p1; + } + + private static class Inner extends Outer { + + final Object p2; + + Inner(final Object p1, final Object p2) { + super(p1); + this.p2 = p2; + } + } + } }