4

My webapp has a non-empty production beans.xml under src/main/resources/META-INF. Now, for my tests, I need to swap out 1 bean with an alternative.

Where do I put this test beans.xml which contains just this and nothing more?

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
  <alternatives>
    <class>...MyTestReplacement</class>
  </alternatives>
</beans>

I tried under src/test/resources/META-INF but that is ignored. I am using arquillian and my test classpath is added to the ShrinkWrap.

Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
  • Note: using `ShrinkWrap...addAsManifestResource(new File("target/test-classes/META-INF/test-beans.xml"), "beans.xml")` does not work, because it overwrites the original `beans.xml` (which is quite large) and that needs to be activated too. – Geoffrey De Smet Sep 12 '11 at 08:38
  • Looks like there 's no answer, so I 've opened an issue: [https://issues.jboss.org/browse/ARQ-585](https://issues.jboss.org/browse/ARQ-585) – Geoffrey De Smet Sep 12 '11 at 09:27
  • Asked on [the seam forum](http://www.seamframework.org/Community/UsingAnAlternativeBeanInTestsWhereToDeclareAlternative) too. – Geoffrey De Smet Sep 22 '11 at 08:22

5 Answers5

5

Even though it's already accepted, ill post you the solution I found. I had the same problem, and using @Specializes was no option for me, because I had many mocks with several methods, thus create for each one a class was a bit overkill....

So in my test I have a ResourceMock:

@Produces
@Alternative
public IResource createResource() {
    Resource resource = mock(Resource.class);
    when(resource.getLocalized(anyString())).then(AdditionalAnswers.returnsFirstArg());
    return resource;
}

With the following ShrinkWrap I was able to load those @Alternative bean only during the test: (no beans.xml in the test dir needed!)

return ShrinkWrap
            .create(JavaArchive.class)
            .addPackages(true, "some.package.with.classes")
            .addAsManifestResource(
                    new StringAsset(
                            "<alternatives><class>my.testclass.with.alternatives</class></alternatives>"),
                    "beans.xml");

And that's it.

bravenoob
  • 83
  • 1
  • 5
3

Don't use @Alternative, but use @Specializes. Just put the @Specializes bean only in your test classpath and it will automatically replace the real bean. No need to mess around with beans.xml.

Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
2

Or, if you need to use @Alternative, you can use a shrinkwrap command .alternativeClass. You can see the following example in the Arquillian-showcase, cdi-ejb subproject. Include this dependency in your pom:

    <dependency>
        <groupId>org.jboss.shrinkwrap.descriptors</groupId>
        <artifactId>shrinkwrap-descriptors-impl</artifactId>
        <scope>test</scope>
    </dependency>

Then use this type of @Deployment (for Glassfish):

    @Deployment
    public static WebArchive createDeploymentForGlassFish() {
    BeansDescriptor beansXml = Descriptors.create(BeansDescriptor.class);

    return ShrinkWrap.create(WebArchive.class)
            .addClasses(FireAndForget.class, FireAndForgetBean.class, BlockingFireAndForgetAlternativeBean.class)
            .addAsWebInfResource(
                    new StringAsset(beansXml.alternativeClass(BlockingFireAndForgetAlternativeBean.class).exportAsString()),
                    beansXml.getDescriptorName());
}

Hope that helps!

Christopher Poile
  • 985
  • 1
  • 11
  • 17
0

In my case I used the code from bellow to specify which beans.xml file to include:

JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
                .addClasses(AutoService.class, AutoServiceCallerImp1.class, AutoServiceCallerImp2.class)
                .addAsManifestResource("META-INF/test.beans.xml", "beans.xml");
cosmintam
  • 81
  • 1
  • 2
0

See http://seamframework.org/Seam3/ModuleTesting or http://ocpsoft.com/seam/cdi-powered-unit-testing-using-arquillian/

Dar Whi
  • 822
  • 5
  • 14
  • These links explain basic usage with arquillian, but neither of which answer the question. – Geoffrey De Smet Sep 12 '11 at 08:36
  • They show how you tell arquillian which configs to use. Or you can provide the content directly without extra file. – Dar Whi Sep 12 '11 at 19:10
  • Problem is that, in both cases, it overwrites the original beans.xml. Duplicating the entire content of the original beans.xml into the test-beans.xml is not maintainable (and violates DRY). – Geoffrey De Smet Sep 22 '11 at 08:23