Hi Romain, I made a gist and wanted your opinion before I submit a PR:
https://gist.github.com/kalgon/ee1e00c0fecdd86afb01fe1a6891454a I don't use MockRegistry or MockitoInjector anymore (everything happens in the extension) and wanted to know if that was ok for you. > From: Xavier Dury <kal...@hotmail.com> > > OK, I'll try to provide a patch when I can find some time. > > > From: Romain Manni-Bucau <rmannibu...@gmail.com> > > > > I think I get the use case. Do you want to try to patch openejb-mockito? > > > > 2017-04-05 13:28 GMT+02:00 Xavier Dury <kal...@hotmail.com>: > > > > > Hi Romain > > > > > > > From: Romain Manni-Bucau <rmannibu...@gmail.com> > > > > > > > > Hi Xavier, > > > > > > > > 2017-04-05 12:22 GMT+02:00 Xavier Dury <kal...@hotmail.com>: > > > > > > > > > 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(); > > > } > > > } > >