For those of you that might struggle with this in the future, the solution is as simple as it should be:

if working with maven, you just make a copy of properties file for the RessourceBundle you want to mock in the src/test/resources, substitute property-values with mocked values and... FIN!

I dunno about the class loader magic but apparently the properties file in test-classes takes precedence.

br
reinis

P.S. I checked source code for RessourceBundleProducer - ProjectStage is NOT being considered whatsoever!

On 21.12.2013 15:10, Romain Manni-Bucau wrote:
Hmm,

If you cant override the producer it is quite hard IMHO

The more common is to use projectstage to determine which value to use...i
dont know if codi supports it btw, did you ask them?
Le 21 déc. 2013 14:19, "Reinis Vicups" <[email protected]> a écrit :

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