I think I get the use case. Do you want to try to patch openejb-mockito?
Romain Manni-Bucau @rmannibucau <https://twitter.com/rmannibucau> | Blog <https://blog-rmannibucau.rhcloud.com> | Old Blog <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> | LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory <https://javaeefactory-rmannibucau.rhcloud.com> 2017-04-05 13:28 GMT+02:00 Xavier Dury <[email protected]>: > Hi Romain > > > From: Romain Manni-Bucau <[email protected]> > > > > Hi Xavier, > > > > 2017-04-05 12:22 GMT+02:00 Xavier Dury <[email protected]>: > > > >> Hi, > >> > >> When using ApplicationComposer, I can declare mocks in my test classes > >> like that: > >> > >> @Mock > >> MyDependency myDependency; > >> > >> @MockInjector > >> public Class<?> mockInjector() { return MockitoInjector.class; } > >> > >> But that does not seem to work with (un@Named) qualified mocks: > > > > Hmm, MockitoInjector has no link with CDI, it is for EJB injections > (which > > are not using CDI/@Inject) > > > >> @Mock > >> @MyQualifier > >> MyDependency myDependency; > > > > This looks like a cdi injection but @Inject is missing > > No, this is no CDI injection, it is the declaration of the qualified mock > in my test class. > That field is set by MockitoAnnotations.initMocks() (through MockInjector). > > >> Of course, I can still make a producer for the qualified mock like this: > >> > >> @Produces > >> @MyQualifier > >> MyDependency myDependency() { return Mockito.mock(MyDependency.class); > } > >> > >> But I wanted to know if that was the only way to do it because, now, I > >> have to programmatically create the mock instead of declaring it with > @Mock. > > > > The openejb-mockito extension only supports @Default and @Any qualifiers > ( > > https://github.com/apache/tomee/blob/master/utils/ > openejb-mockito/src/main/java/org/apache/openejb/mockito/ > MockitoExtension.java) > > but no real blocker to support another one. The only issue is to define > how > > to select an instance based on a qualifier then. > > > > Note: @Named is not a "real" qualifier so you actually used @Default I > think > > When MockRegistry is looping on all the fields of the TestInstance to > gather > the mocks created by MockitoAnnotations.initMocks(), it should also keep > all > qualifiers declared on the field. > > Of course, this is not trivial with stereotypes and qualifiers added at > runtime > through BeforeBeanDiscover.addQualifier() (but all annotations could be > kept and > filtered in the MockitoExtension which has access to the BeanManager). > > MockitoExtension would then need to register a bean for each mock with the > correct type AND qualifiers. > > Here is a full example of what I want to do: > > @RunWith(ApplicationComposer.class) > @Classes(cdi = true, innerClassesAsBean = true) > public class MyTest { > > public static class MyBean { > > @Inject > @MyQualifier > public MyInterface myInterface; > > public void printMessage() { > System.out.println(myInterface.getMessage()); > } > } > > public interface MyInterface { > String getMessage(); > } > > @Retention(RetentionPolicy.RUNTIME) > @Qualifier > public @interface MyQualifier {} > > @Inject > private MyBean myBean; > > @Mock > @MyQualifier > private MyInterface myInterface; > > @Test > public void test() { > Mockito.doReturn("Hello world!").when(myInterface).getMessage(); > myBean.printMessage(); > Mockito.verify(myInterface).getMessage(); > } > > @MockInjector > public Class<? extends FallbackPropertyInjector> mockInjector() { > return MockitoInjector.class; > } > } > > Currently, that does not work because MyBean.myInterface won't be resolved. > > My current workaround is: > > @RunWith(ApplicationComposer.class) > @Classes(cdi = true, innerClassesAsBean = true) > public class MyTest { > > public static class MockProducer { > > @Produces > @MyQualifier > static MyInterface myInterface = Mockito.mock(MyInterface.class); > } > > public static class MyBean { > > @Inject > @MyQualifier > public MyInterface myInterface; > > public void printMessage() { > System.out.println(myInterface.getMessage()); > } > } > > public interface MyInterface { > String getMessage(); > } > > @Retention(RetentionPolicy.RUNTIME) > @Qualifier > public @interface MyQualifier {} > > @Inject > private MyBean myBean; > > @Inject > @MyQualifier > private MyInterface myInterface; > > @Test > public void test() { > Mockito.doReturn("Hello world!").when(myInterface).getMessage(); > myBean.printMessage(); > Mockito.verify(myInterface).getMessage(); > } > }
