There are a few approaches to test CDI code such as using @Alternative
and/or mocking. Another approach, presented here is to use the JGlue project - more exactly the CDI-Unit which is a JUnit4 test runner
that enables unit testing Java CDI applications.
For example, let's consider the application from post Inject
a Java logger via a CDI producer method - in this application you saw exactly
what the name of the post say, how to inject a Java logger via a producer
method. Now, let's suppose that we want to write a JUnit test for the method FooBean#logBuzzAction():
@Named
@RequestScoped
public
class FooBean {
@Inject
Logger fooLog;
public void logFooAction() {
fooLog.info("Log message from FooBean
!");
}
}
In a pretty dummy approach we can try this:
public
class LoggerTest {
@Inject
FooBean fooBean;
@Test
public void testStart() {
fooBean.logFooAction();
}
}
Well, obviously this will not work! The problem will be caused by
the @Inject
part, so is time to find a solution. Add quickly the CDI-Unit dependency in the
POM:
<dependency>
<groupId>org.jglue.cdi-unit</groupId>
<artifactId>cdi-unit</artifactId>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
And specify @RunWith(CdiRunner.class) on your JUnit4 test class
to enable injection directly into the test class:
@RunWith(CdiRunner.class)
public
class LoggerTest {
@Inject
FooBean fooBean;
@Test
public void testStart() {
fooBean.logFooAction();
}
}
Ok, the FooBean is injected now! But, now we have
an unsatisfied dependencies for type Logger. In order to fix this issue, simply specify MyLogger
class as an additional class for this test. This will tell CDI-Unit to explicitly add a class to the CDI
environment:
@RunWith(CdiRunner.class)
@AdditionalClasses(MyLogger.class)
public
class LoggerTest {
@Inject
FooBean fooBean;
@Test
public void testStart() {
fooBean.logFooAction();
}
}
Ok, the last issue that we must solve consist in the fact that
there is no active contexts for the request scope, but CDI-Unit has built in
support for request, session and conversation scopes using @InRequestScope,
@InSessionScope
and @InConversationScope.
So, let's bring the context in:
@RunWith(CdiRunner.class)
@AdditionalClasses(MyLogger.class)
public
class LoggerTest {
@Inject
FooBean fooBean;
@Test
@InRequestScope
public void testStart() {
fooBean.logFooAction();
}
}
Done! Now the test is ready and you can see it here.
Niciun comentariu :
Trimiteți un comentariu