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
{{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
|