Unsatisfied dependencies with Weld during integration testing
Asked Answered
U

3

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?

Unsocial answered 24/1, 2017 at 18:48 Comment(10)
May be you should find a way to register the SomeService implementation as Cdi-Unit does with the @AdditionnalClasses annotation.Amblygonite
Are you sure that you have an implementation of SomeService available on the test classpath?Leralerch
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.Zoellick
@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?Unsocial
@Zoellick I really need to make it work extending BlockJUnit4ClassRunner because I'll need some customization...Unsocial
I edited my question, it seems like Weld only looks into src/test/java...Unsocial
Take a look at this link: 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 ServiceAmblygonite
@Amblygonite 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.Unsocial
@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?Amblygonite
@Amblygonite 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?Unsocial
U
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)

Unsocial answered 27/1, 2017 at 16:10 Comment(1)
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.Debbi
L
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.

Leralerch answered 26/1, 2017 at 7:42 Comment(1)
I wish I could just avoid Weld and use Spring ;-)Unsocial
A
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.

Amblygonite answered 27/1, 2017 at 8:8 Comment(1)
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.Unsocial

© 2022 - 2024 — McMap. All rights reserved.