Skip to content

Cannot use @InjectMock with mybatis Mapper interfaces #217

Closed
@Leibnizhu

Description

@Leibnizhu

I'm trying to mock a mybatis Mapper interface for unit test.

The mapper interface is like :

@Mapper
public interface XxxMapper  {
   @Select("SELECT count(*) FROM xxx")
    long count();
}

unit test:

@QuarkusTest
public class XxxServiceTest {
    @InjectMock
    XxxMapper xxxMapper;

    @Test
    void countTest() {
        Mockito.when(xxxMapper.count()).thenReturn(100L);
        System.out.println(xxxMapper.count());
    }
}

Running this test will fail with :

org.junit.jupiter.api.extension.TestInstantiationException: Failed to create test instance
	at io.quarkus.test.junit.QuarkusTestExtension.initTestState(QuarkusTestExtension.java:793)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:752)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        ..............
Caused by: java.lang.IllegalStateException: Invalid use of io.quarkus.test.junit.mockito.InjectMock - the injected bean does not declare a CDI normal scope but: javax.inject.Singleton. Offending field is xxxMapper of test class class com.github.leibnizhu.XxxServiceTest
	at io.quarkus.test.junit.mockito.internal.CreateMockitoMocksCallback.getBeanInstance(CreateMockitoMocksCallback.java:115)
	at io.quarkus.test.junit.mockito.internal.CreateMockitoMocksCallback.afterConstruct(CreateMockitoMocksCallback.java:36)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.test.junit.QuarkusTestExtension.initTestState(QuarkusTestExtension.java:782)
	... 65 more

As https://quarkus.io/guides/getting-started-testing#further-simplification-with-injectmock said:

By default, the @InjectMock annotation can be used for any normal CDI scoped bean (e.g. @ApplicationScoped, @RequestScoped). Mocking @singleton beans can be performed by setting the convertScopes property to true (such as @InjectMock(convertScopes = true). This will convert the @singleton bean to an @ApplicationScoped bean for the test.

I tried convertScopes = true :

    @InjectMock(convertScopes = true)
    XxxMapper xxxMapper;

but the test still failed with the same error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions