7
votes

I am able to deploy a RESTEasy application working well with Weld (meaning my CDI works) but I am having some trouble with my integration tests. I get this error:

org.jboss.weld.exceptions.DeploymentException:
WELD-001408: Unsatisfied dependencies for type SomeService with qualifiers @Default

while testing:

@RunWith(WeldJUnit4Runner.class)
public class SomeServiceIT {

    @Inject
    private SomeService service;

    @Test
    public void test() {
        System.out.println(service);
    }
}

The last message in my logs is

DEBUG::WELD-000100: Weld initialized. Validating beans

Content of src/test/resources/META-INF/beans.xml:

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

By the way I tried the cdi-unit library and it works, but I need to use my own WeldJUnit4Runner which is currently:

public class WeldJUnit4Runner extends BlockJUnit4ClassRunner {

    private final Weld weld;
    private final WeldContainer container;

    public WeldJUnit4Runner(Class<?> klass) throws InitializationError {
        super(klass);
        this.weld = new Weld();
        this.container = weld.initialize();
    }

    @Override
    protected Object createTest() throws Exception {
        return container.instance().select(getTestClass().getJavaClass()).get();
    }
}

I use weld-se 2.4.1.Final for testing.
Thanks.

EDIT:
So it seems like Weld only looks into src/test/java (when I copy SomeService over to src/test/java it woks). This is silly, I am not going to duplicate all my classes to test them... How to tell Weld to retrieve classes from src/main/java?

3
May be you should find a way to register the SomeService implementation as Cdi-Unit does with the @AdditionnalClasses annotation. - Rouliboy
Are you sure that you have an implementation of SomeService available on the test classpath? - G. Demecki
If this works out of the test and not here, that means your test framework is not operating well with CDI - e.g. not seeing the beans perhaps. From my own experience I would advise you to try testing CDI/Weld with Arquillian. - Siliarus
@G.Demecki cdi-unit finds it and when I deploy it works. What else there is to do in addition to what I have done already to make Weld discover the beans? - Maxime Laval
@Siliarus I really need to make it work extending BlockJUnit4ClassRunner because I'll need some customization... - Maxime Laval

3 Answers

4
votes

So I was able to make it work by creating src/main/resources/META-INF/beans.xml in addition to the existing src/main/webapp/WEB-INF/beans.xml and src/test/resources/META-INF/beans.xml meaning now I have 3 times the exact same file in the same project which I find silly but I guess this is how it is in the Weld world...

Thanks all for your time.

EDIT:
Actually I am able to deploy the application with only src/main/resources/META-INF/beans.xml (I removed src/main/webapp/WEB-INF/beans.xml)

0
votes

Sorry, I have no solution, but only a small clue: if you want to do some customizations of the BlockJUnit4ClassRunner - why don't you try to extend the org.jglue.cdiunit.CdiRunner or org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner? Or at least take a look at their source code.

Ps. I always find Weld's class-path scanning brittle & error prone. And try to avoid it as much as possible.

0
votes

It should work so I post here what I did.

Firstly, I use :

  • Eclipse Luna
  • JDK 7

The tree of my project is the following one :

enter image description here

Here are my pom dependencies :

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se-core</artifactId>
    <version>2.4.1.Final</version>
    <scope>test</scope>
</dependency>

The SomeService interface :

package org.jvi.cdirunner;

public interface SomeService {

    void test();
}

The SomeServiceImpl implementation :

package org.jvi.cdirunner;   

public class SomeServiceImpl implements SomeService {

    @Override
    public void test() {
        // TODO Auto-generated method stub
    }

}

And the test to run :

package org.jvi.cdirunner.test;

import javax.inject.Inject;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.jvi.cdirunner.SomeService;

@RunWith(WeldJUnit4Runner.class)
public class SomeServiceIT {

    @Inject
    private SomeService service;

    @Test
    public void test() {
        System.out.println(service);
    }
}

And everything works fine if I run the test under Eclipse. I can't figure out why it doesn't work on your side.