7

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?

Maxime Laval
  • 4,068
  • 8
  • 40
  • 60
  • May be you should find a way to register the `SomeService` implementation as Cdi-Unit does with the @AdditionnalClasses annotation. – Rouliboy Jan 24 '17 at 19:34
  • Are you sure that you have an implementation of `SomeService` available on the test classpath? – G. Demecki Jan 25 '17 at 08:04
  • 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 Jan 25 '17 at 09:00
  • @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 Jan 25 '17 at 15:33
  • @Siliarus I really need to make it work extending BlockJUnit4ClassRunner because I'll need some customization... – Maxime Laval Jan 25 '17 at 15:42
  • I edited my question, it seems like Weld only looks into src/test/java... – Maxime Laval Jan 25 '17 at 16:45
  • Take a look at this link: http://memorynotfound.com/java-se-unit-testing-cdi-junit-jboss-weld-se/ . The way you implémented your runner, you need to provide an implementation of tour Service – Rouliboy Jan 25 '17 at 17:02
  • @Rouliboy I tried to apply that tutorial to my project already and it didn't work, then I wanted to download it and test it as is but there are some permission problems with the zip file, the extraction fails. – Maxime Laval Jan 25 '17 at 17:18
  • @Maxime : I tested your code and it works fine for me. Which version of Junit do you have? I tested with Junit 4.11, weld-se 2.4.1.Final, javaee-api 7.0. Are you sure your beans.xml is present in test/resources/META-INF? How do you launch your test? – Rouliboy Jan 25 '17 at 22:01
  • @Rouliboy I tried with JUnit 4.12 and 4.11, yes I have beans.xml in test/resources/META-INF (if you don't you get an error telling you it's missing), I run the test in Eclipse "Run As > JUnit test". You have no other configuration or specific annotations in the class you inject and the class containing your test? – Maxime Laval Jan 26 '17 at 21:10

3 Answers3

4

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)

Maxime Laval
  • 4,068
  • 8
  • 40
  • 60
  • Thanks. beans.xml unter src/test/resources also solved it for me. My SomeService was in a different maven-module and it seems DeltaSpike needs all the configuration in every referenced module as well. – Thomas Jul 31 '19 at 13:02
0

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.

G. Demecki
  • 10,145
  • 3
  • 58
  • 58
0

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.

Rouliboy
  • 1,377
  • 1
  • 8
  • 21
  • Thanks for taking the time to write such a detailed answer :-) I created a new project from scratch with your code and it works, btw I think there is a mistake in your code at `import fr.pe.cdirunner.SomeService;` instead of `import org.jvi.cdirunner.SomeService;` t'es français ? Anyway I figured it out and I'll post an answer. – Maxime Laval Jan 27 '17 at 16:02