I am trying to use Weld SE 2.3.0.Final to swap an alternative implementation of an injected dependency during testing by supplying a different beans.xml in src/test/resources/META-INF
It always seems to use the main version of beans.xml though and I'm not sure why.
First of all here are the supporting classes
Engine.java
{{ ```java public interface Engine { void start(); void stop(); } }} ``` DefaultEngine.java
{{@Vetoed public class DefaultEngine implements Engine {
public void start() { System.out.println("Cough cough vrummmmm"); }
public void stop() { System.out.println("Phhhut clank"); }
}}}
Car.java
{{public class Car { @Inject private Engine engine;
public void startCar() { engine.start(); }
public void stopCar() { engine.stop(); }
}}}
EngineProducer.java
{{public class EngineProducer {
@Produces public Engine getEngine() { return new DefaultEngine(); }
}}}
App.java
{{public class App { @Inject private Car car;
public void main(@Observes ContainerInitialized event) { car.startCar(); car.stopCar(); } }}}
And the production version of beans.xml in src/main/resources/META-INF
{{<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" version="1.1" bean-discovery-mode="all"> </beans>}}
The above code when run from App.java should print (and it does)
{{Cough cough vrummmmm Phhhut clank}}
Now from the test code I want to use the SportsEngine implementation. So I have the following
SportsEngine.java
{{@Vetoed public class SportsEngine implements Engine {
public void start() { System.out.println("Vrummm vrummm vrummmm!"); }
public void stop() { System.out.println("Prrrrrr clunk"); }
}}}
TestEngineProducer.java
{{@Alternative public class TestEngineProducer {
@Produces public Engine getEngine() { return new SportsEngine(); }
}}}
AppTest.java
{{@RunWith(WeldJUnit4Runner.class) public class AppTest {
@Inject private Car car;
@Test public void testCar() { car.startCar(); car.stopCar(); }
}}} WeldJUnit4Runner.java
{{public class WeldJUnit4Runner extends BlockJUnit4ClassRunner {
/** The test class to run. */ private final Class<?> mKlass; /** Weld infrastructure. */ private final Weld weld; /** The container itself. */ private final WeldContainer container;
/** * Runs the class passed as a parameter within the container. * * @param klass * to run * @throws InitializationError * if anything goes wrong. */ public WeldJUnit4Runner(final Class<Object> klass) throws InitializationError { super(klass); this.mKlass = klass; this.weld = new Weld(); this.container = weld.initialize(); }
@Override protected Object createTest() throws Exception { final Object test = container.instance().select(mKlass).get(); return test; } }}} And the test version of beans.xml in src/test/resources/META-INF
{{<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" version="1.1" bean-discovery-mode="all"> <alternatives> <class>com.test.testing.TestEngineProducer</class> </alternatives> </beans>}}
When the test method is run it should print
{{Vrummm vrummm vrummmm! Prrrrrr clunk}}
But instead it seems to use the EngineProducer instead of the TestEngineProducer and prints the output twice
{{Cough cough vrummmmm Phhhut clank Cough cough vrummmmm Phhhut clank}}
Why is it not using the test beans.xml?
If I put the <alternatives> section from test beans.xml and put it in the main beans.xml then it works, but I don't want to swap the beans.xml in main/resources/META-INF when I'm testing
|