Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArrayIndexOutOfBoundsException with Version 5.3.1 #3000

Closed
KaiSuchomel opened this issue May 5, 2023 · 10 comments · Fixed by #3190
Closed

ArrayIndexOutOfBoundsException with Version 5.3.1 #3000

KaiSuchomel opened this issue May 5, 2023 · 10 comments · Fixed by #3190

Comments

@KaiSuchomel
Copy link

KaiSuchomel commented May 5, 2023

Hey, after migrated to Version 5.3.1 i get the following Error during Testexecution:

java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
	at org.mockito.internal.configuration.injection.filter.TypeBasedCandidateFilter.recurseOnTypeArguments(TypeBasedCandidateFilter.java:96)
	at org.mockito.internal.configuration.injection.filter.TypeBasedCandidateFilter.isCompatibleTypes(TypeBasedCandidateFilter.java:51)
	at org.mockito.internal.configuration.injection.filter.TypeBasedCandidateFilter.recurseOnTypeArguments(TypeBasedCandidateFilter.java:145)
	at org.mockito.internal.configuration.injection.filter.TypeBasedCandidateFilter.isCompatibleTypes(TypeBasedCandidateFilter.java:51)
	at org.mockito.internal.configuration.injection.filter.TypeBasedCandidateFilter.filterCandidate(TypeBasedCandidateFilter.java:167)
	at org.mockito.internal.configuration.injection.PropertyAndSetterInjection.injectMockCandidatesOnFields(PropertyAndSetterInjection.java:136)
	at org.mockito.internal.configuration.injection.PropertyAndSetterInjection.injectMockCandidates(PropertyAndSetterInjection.java:113)
	at org.mockito.internal.configuration.injection.PropertyAndSetterInjection.processInjection(PropertyAndSetterInjection.java:81)
	at org.mockito.internal.configuration.injection.MockInjectionStrategy.process(MockInjectionStrategy.java:68)
	at org.mockito.internal.configuration.injection.MockInjectionStrategy.relayProcessToNextStrategy(MockInjectionStrategy.java:91)
	at org.mockito.internal.configuration.injection.MockInjectionStrategy.process(MockInjectionStrategy.java:71)
	at org.mockito.internal.configuration.injection.MockInjectionStrategy.relayProcessToNextStrategy(MockInjectionStrategy.java:91)
	at org.mockito.internal.configuration.injection.MockInjectionStrategy.process(MockInjectionStrategy.java:71)
	at org.mockito.internal.configuration.injection.MockInjection$OngoingMockInjection.apply(MockInjection.java:88)
	at org.mockito.internal.configuration.DefaultInjectionEngine.injectMocksOnFields(DefaultInjectionEngine.java:26)
	at org.mockito.internal.configuration.InjectingAnnotationEngine.injectCloseableMocks(InjectingAnnotationEngine.java:118)
	at org.mockito.internal.configuration.InjectingAnnotationEngine.processInjectMocks(InjectingAnnotationEngine.java:61)
	at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:48)
	at org.mockito.MockitoAnnotations.openMocks(MockitoAnnotations.java:81)
	at org.mockito.internal.framework.DefaultMockitoSession.<init>(DefaultMockitoSession.java:43)
	at org.mockito.internal.session.DefaultMockitoSessionBuilder.startMocking(DefaultMockitoSessionBuilder.java:83)
	at org.mockito.junit.jupiter.MockitoExtension.beforeEach(MockitoExtension.java:153)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$2(TestMethodTestDescriptor.java:166)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:202)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:202)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:165)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:132)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
	Suppressed: java.lang.NullPointerException: Cannot invoke "java.util.Set.forEach(java.util.function.Consumer)" because the return value of "org.junit.jupiter.api.extension.ExtensionContext$Store.remove(Object, java.lang.Class)" is null
		at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:184)
		at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachCallbacks$12(TestMethodTestDescriptor.java:260)
		at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:276)
		at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
		at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$14(TestMethodTestDescriptor.java:276)
		at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
		at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:275)
		at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:259)
		at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:144)
		... 49 more

The Test runs under 5.1.0 without any Issue!!

The Test looks like the following (just snippets):
Testclass:

@ExtendWith(MockitoExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class StorageMessageBaseControllerTest {

    @Mock
    Instance<Storable<?>> storableInstance;
    @Mock
    EntityManager em;
    @Spy
    @InjectMocks
    StorageMessageBaseController testee;

Controller:

@Dependent
public class StorageMessageBaseController extends MessageControllerBase<StorageMessage>, Storable> {

    @Inject
    Instance<AbstractEntityController<? extends Storable, ?>> controllerInstance;
    @Inject
    @WithCaching
    Instance<Storable<?>> storableInstance;
    @Inject
    ObjectMapper objectMapper;

When i remove the controllerInstance (only for testing) field in production code, the test runs.....
Anyone a clue whats causing this behaviour.

@TimvdLippe
Copy link
Contributor

@jfrantzius We got another one here related to @InjectMocks 😢

@relyativus
Copy link

Hey. Facing the same outcome with a different use-case:

Base class:

public class BaseService<E, I extends Serializable> {

    ...

    private BaseRepository<E, I> repository;

    ...
}

Class with injection:

public class UnderTest extends BaseService<One, Two> {

   private OneRepository oneRepository;
   private TwoRepository twoRepository;
}

Test:

@MockitoSettings
public class JunitTest {

  @Mock
  OneRepository oneRepository;

  @Mock
  TwoRepository twoRepository;

  @InjectMocks
  UnderTest underTest;
}

Both repositories implement BaseRepository with different generic types. It works ok on 5.2.0, though the base class repository property is not injected. In 5.3.1, it tries to inject the base class repository field but fails with the error described by @KaiSuchomel. Also works, if there's only one candidate to inject(e.g. only OneRepository)

nineninesevenfour added a commit to nineninesevenfour/mockito that referenced this issue Jun 13, 2023
Signed-off-by: Harald Fassler <harald.fassler+9974@gmail.com>
@davidreis97
Copy link

We're also affected by this issue.

nineninesevenfour added a commit to nineninesevenfour/mockito that referenced this issue Sep 25, 2023
Signed-off-by: Harald Fassler <harald.fassler+9974@gmail.com>
@davidreis97
Copy link

Is there a plan to address this?

@jfrantzius
Copy link
Contributor

Hi @relyativus ,
in your test code, what does BaseRepository refer to here?

public class BaseService<E, I extends Serializable> {

    ...

    private BaseRepository<E, I> repository;

    ...
}

It would be good to have a self-contained reproducer ...

@relyativus
Copy link

relyativus commented Nov 30, 2023

Hi @jfrantzius
It's an interface:

public interface BaseRepository<E, I extends Serializable> {
      E findById(I id);
      E save(E entity);
}

and the OneRepository and TwoRepository are the implementations that set specific types to generics:

public class OneRepository implements BaseRepository<Map<String,String>,String>{
     Map<String,String> findById(String id) { return Map.of();}
     Map<String,String> save(Map<String,String> entity) {return entity;} 
}

The real-world scenario is based on Spring Data repositories

@jfrantzius
Copy link
Contributor

jfrantzius commented Nov 30, 2023

Thx, then what are One and Two referring to here?

public class UnderTest extends BaseService<One, Two> {
   private OneRepository oneRepository;
   private TwoRepository twoRepository;
}

Just some dumb and empty Pojos?

@relyativus
Copy link

@jfrantzius This is the two different implementations of BaseRepository, but with different generics. E.g.

public class OneRepository implements BaseRepository<Map<String,String>,String>{
     Map<String,String> findById(String id) { return Map.of();}
     Map<String,String> save(Map<String,String> entity) {return entity;} 
}

public class TwoRepository implements BaseRepository<Integer,String>{
     Integer findById(String id) { return Map.of();}
     Integer save(Integer entity) {return entity;} 
}

@jfrantzius
Copy link
Contributor

jfrantzius commented Dec 1, 2023

@relyativus what I meant is the One and Two in this line: public class UnderTest extends BaseService<One, Two>

@relyativus
Copy link

@jfrantzius Oh, I see. Yeah, simple pojos

jfrantzius pushed a commit to jfrantzius/mockito that referenced this issue Dec 1, 2023
jfrantzius pushed a commit to jfrantzius/mockito that referenced this issue Dec 1, 2023
jfrantzius pushed a commit to jfrantzius/mockito that referenced this issue Dec 1, 2023
TimvdLippe pushed a commit that referenced this issue Dec 1, 2023
Fixes #3000

Co-authored-by: Jörg von Frantzius <joerg.frantzius@aperto.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants