Hi,

thank you for your suggestion, Romain. Alas the case turns out to be more complex as expected:

Within unittest I test some complex business function. This function uses other injected RessourceBundles that I do NOT want to mock.

Example: I use one RessourceBundle to store connection strings and other RessourceBundle to store translations. If I exclude RessourceBundle and RessourceBundleProducer from classes, NONE of RessourceBundles get injected and I get NPEs later in my business function.

Different RessourceBundles are identified by different Qualifiers such as these:

    @Mock
    @Bundle(SchedulerConfiguration.class)
    private transient ResourceBundle schedulerConfiguration;

and later in business controller

    @Inject
    @Bundle(MyRessourceTranslations.class)
private transient ResourceBundle myRessourceTranslations; // <- I get NPE later in business function when calling myRessourceTranslations.getValue("somestring")

Thank you guys for your help! Would be great to find some sort of solution for this case (case where I want to mock just some RessourceBundles while others - not)

br
reinis


On 21.12.2013 13:40, Romain Manni-Bucau wrote:
Hi

Why do you put it in classes if you mock it? Just replace it by your mock
in this list.
Le 21 déc. 2013 12:03, "Reinis Vicups" <[email protected]> a écrit :

Hi everyone,

in my testcase I would like to Mock org.apache.myfaces.extensions.
cdi.core.api.resource.bundle.ResourceBundle (so that I can return test
connection strings instead of production-ones). My unittest is set-up to
run with org.apache.openejb.junit.ApplicationComposer and Mockito.

Testcase:

import org.mockito.Mock;
import org.apache.myfaces.extensions.cdi.core.api.resource.bundle.Bundle;

@RunWith(ApplicationComposer.class)
public class AzureSchedulerWorkerTest {
...
     @Mock
     @Bundle(SchedulerConfiguration.class)
     private transient ResourceBundle schedulerConfiguration;
...
     @MockInjector
     public Class<?> mockitoInjector() {
         return MockitoInjector.class;
     }

     @Module
     public Class<?>[] classes() {
         return new Class<?>[] { ... ResourceBundle.class,
ResourceBundleProducer.class, ... };
     }

     @Test
     public void testSomething() {
         ...
when(schedulerConfiguration.getValue(SchedulerConfiguration.
StorageConnectionString.class)).thenReturn("UseDevelopmentStorage=true");
         ...
     }
}

Currently I receive following exception:

SEVERE: CDI Beans module deployment failed
org.apache.webbeans.exception.inject.DeploymentException:
javax.enterprise.inject.AmbiguousResolutionException: Ambiguous resolution
found beans:
ResourceBundle, Name:null, WebBeans Type:PRODUCERMETHOD, API
Types:[org.apache.myfaces.extensions.cdi.core.api.resource.bundle.
ResourceBundle,java.io.Serializable,java.lang.Object],
Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]
from jar:file:/.m2/repository/org/apache/myfaces/extensions/cdi/
core/myfaces-extcdi-core-impl/1.0.5/myfaces-extcdi-core-
impl-1.0.5.jar!/org/apache/myfaces/extensions/cdi/core/
impl/resource/bundle/ResourceBundleProducer.class
ResourceBundle, Name:null, WebBeans Type:THIRDPARTY, API
Types:[org.apache.myfaces.extensions.cdi.core.api.resource.bundle.
ResourceBundle,java.io.Serializable], Qualifiers:[javax.enterprise.
inject.Any,javax.enterprise.inject.Default] from
jar:file:/.m2/repository/org/apache/myfaces/extensions/cdi/
core/myfaces-extcdi-core-api/1.0.5/myfaces-extcdi-core-api-
1.0.5.jar!/org/apache/myfaces/extensions/cdi/core/api/resource/bundle/
ResourceBundle.class
     at org.apache.webbeans.config.BeansDeployer.deploy(
BeansDeployer.java:217)
     at org.apache.openejb.cdi.OpenEJBLifecycle.startApplication(
OpenEJBLifecycle.java:187)
     at org.apache.openejb.cdi.ThreadSingletonServiceImpl.initialize(
ThreadSingletonServiceImpl.java:162)
     at org.apache.openejb.cdi.CdiBuilder.build(CdiBuilder.java:43)
     at org.apache.openejb.assembler.classic.Assembler.
createApplication(Assembler.java:799)
     at org.apache.openejb.assembler.classic.Assembler.
createApplication(Assembler.java:612)
     at org.apache.openejb.assembler.classic.Assembler.
createApplication(Assembler.java:608)
     at org.apache.openejb.testing.ApplicationComposers.before(
ApplicationComposers.java:639)
     at org.apache.openejb.testing.ApplicationComposers.evaluate(
ApplicationComposers.java:722)
     at org.apache.openejb.junit.ApplicationComposer$
DeployApplication.evaluate(ApplicationComposer.java:64)
     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(
BlockJUnit4ClassRunner.java:70)
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(
BlockJUnit4ClassRunner.java:50)
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
     at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(
JUnit4TestReference.java:50)
     at org.eclipse.jdt.internal.junit.runner.TestExecution.
run(TestExecution.java:38)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.
runTests(RemoteTestRunner.java:467)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.
runTests(RemoteTestRunner.java:683)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.
run(RemoteTestRunner.java:390)
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.
main(RemoteTestRunner.java:197)
Caused by: javax.enterprise.inject.AmbiguousResolutionException:
Ambiguous resolution
found beans:
ResourceBundle, Name:null, WebBeans Type:PRODUCERMETHOD, API
Types:[org.apache.myfaces.extensions.cdi.core.api.resource.bundle.
ResourceBundle,java.io.Serializable,java.lang.Object],
Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]
from jar:file:/.m2/repository/org/apache/myfaces/extensions/cdi/
core/myfaces-extcdi-core-impl/1.0.5/myfaces-extcdi-core-
impl-1.0.5.jar!/org/apache/myfaces/extensions/cdi/core/
impl/resource/bundle/ResourceBundleProducer.class
ResourceBundle, Name:null, WebBeans Type:THIRDPARTY, API
Types:[org.apache.myfaces.extensions.cdi.core.api.resource.bundle.
ResourceBundle,java.io.Serializable], Qualifiers:[javax.enterprise.
inject.Any,javax.enterprise.inject.Default] from
jar:file:/.m2/repository/org/apache/myfaces/extensions/cdi/
core/myfaces-extcdi-core-api/1.0.5/myfaces-extcdi-core-api-
1.0.5.jar!/org/apache/myfaces/extensions/cdi/core/api/resource/bundle/
ResourceBundle.class
     at org.apache.webbeans.util.InjectionExceptionUtil.
throwAmbiguousResolutionExceptionForBeans(InjectionExceptionUtil.java:104)
     at org.apache.webbeans.util.InjectionExceptionUtil.
throwAmbiguousResolutionException(InjectionExceptionUtil.java:94)
     at org.apache.webbeans.util.InjectionExceptionUtil.
throwAmbiguousResolutionException(InjectionExceptionUtil.java:71)
     at org.apache.webbeans.container.InjectionResolver.resolve(
InjectionResolver.java:699)
     at org.apache.webbeans.container.InjectionResolver.
checkInjectionPoint(InjectionResolver.java:191)
     at org.apache.webbeans.container.BeanManagerImpl.validate(
BeanManagerImpl.java:954)
     at org.apache.webbeans.config.BeansDeployer.validate(
BeansDeployer.java:470)
     at org.apache.webbeans.config.BeansDeployer.validateInjectionPoints(
BeansDeployer.java:420)
     at org.apache.webbeans.config.BeansDeployer.deploy(
BeansDeployer.java:200)
     ... 24 more

My question is - why does this happen and how to fix it?

I am guessing the issue could be that @Mock uses own Producer (or other
magic) to do the injection and then there's ResourceBundleProducer. This
assumption however does not explain the listed beans in AmbiguousException
(I would expect two ambiguous producers).

I was thinking to @Specialize ResourceBundleProducer and control what is
being produced but that's hell of a construct just to substitute basically
a property file.

Any comments or suggestions are greatly appreciated!

br
reinis

Reply via email to