Marc von Renteln Marc von Renteln - 7 months ago 63
Java Question

Cucumber CDI injection does not work with beans in src/main/java

I have a JEE application in a maven project using JUnit and Cucumber to test my code. The application is using CDI with weld-se in test scope.

I have created a simple feature file

src/test/resources/specification/first.feature


Scenario: Identified user
Given I am user A


Then I created the corresponding cucumber step:

public class FirstSteps {

@Inject
UserService userService;

@Given("^I am user A$")
public void i_am_user_A() throws Throwable {
User user = User.new().withName("user A").create();
assertThat(userService.getActualUser()).isEqualTo(user);
}

}


User Service is an Interface with one trivial implementation:

public interface UserService {
User getActualUser();
}

public class FakeUserService implements UserService {

@Override
public User getActualUser() {
return User.new().withName("user A").create();
}

}


There are empty beans.xml files in
src/main/resources/META-INF
and
src/test/resources/META-INF
.

The step is located in
src/test/resources
, the service interface and its implementation in
src/main/java
.

And here is the JUnit-Test for it:

@RunWith(Cucumber.class)
@CucumberOptions(
features = {"classpath:specifikation"},
glue = {"mypackage"})
public final class CucumberTests {
}


The step is found by cucumber and gets executed. But CDI does not work:

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type UserService with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject mypackage.FirstSteps.userService


I have found this issue on github for cucumber. But the solution does not work for me. I already have two empty beans.xml files in
src/main/resources/META-INF
and
src/test/resources/META-INF
.

It seems like the weld container creates a context for
src/test
only and everything in
src/main
does not belong to it. When I move the service interface and implementation to
src/test/java
it works...

Is there a way to reference beans in
src/main
from
src/test
?

EDIT: corrected location of the service interface

Answer

Assuming that your step is located in src/test/java and your service (interface) is located in src/main/java and not in src/(test|main)/resources (typo?), your setup should work.

Maybe check the following:

  1. Ensure that your src/main/java and src/test/java folders are on the same classpath.
  2. Assuming that you are using a current version of Weld which is CDI >1.1 compliant, ensure that both folders are explicit bean archives.
  3. Ensure your beans.xml files are literally empty or have bean-discovery-mode set to all.

If that does not work either, try to annotate your FakeUserService.