DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Weld + JUnit = Easy Testing of CDI Beans

Weld + JUnit = Easy Testing of CDI Beans

Lots can go wrong in a unit test incorrectly performed. Weld now has an extension that could help you keep everything together.

Matěj Novotný user avatar by
Matěj Novotný
·
Martin Kouba user avatar by
Martin Kouba
·
Jan. 25, 18 · Tutorial
Like (4)
Save
Tweet
Share
38.00K Views

Join the DZone community and get the full member experience.

Join For Free

There is no doubt that unit testing is essential for many applications. But if you have a unit test for a CDI bean without running actual CDI container, quite a few issues arise. Starting with field injection simulations, then extending to interceptors, decorators, events, programmatic lookup — all in all, it quickly becomes quite a challenge. This is where we usually reach for mocking frameworks. But use too many mocks and things get tangled really quickly. Of course, there are still integration tests. But integration tests are usually more time and resource-consuming.

So here comes Weld JUnit extension, which allows you to use an actual CDI container instead of complex simulations. This extension boots up Weld before each test run and shuts it down afterwards. This means that you can leverage all bean capabilities (injection, interception, events, etc.) in your tests. Of course, you have the power to customize what beans, extensions, interceptors (and so forth) are going to be in the container. Besides, it's easy to combine this approach with mocking frameworks. As a matter of fact, some convenient tools to allow easy mocking are already baked into the extension.

Key Features

  • Supports JUnit 4 and JUnit 5

  • Supports Weld 2.4 (CDI 1.2) and Weld 3.0 (CDI 2.0)

  • Test class injection

  • Mocking

    • Convenient tools to add mock beans and interceptors

    • Mock injection services (e.g. to mock @Resource and @EJB injection points)

    • Mock contexts for normal scopes

Get Started

First, add the Maven artifact to your pom.xml:

<dependency>
  <groupId>org.jboss.weld</groupId>
  <artifactId>weld-junit5</artifactId>
  <version>${version.weld-junit}</version>
  <scope>test</scope>
</dependency>

NOTE: We will be using JUnit 5 for demonstration purposes. If you wish to know more about JUnit 4, please refer to these guidelines.

Let's start with the simplest possible test:

/**
 * 1. Weld container is started/stopped automatically.
 * 2. By default, only the content of the test package is discovered by Weld.
 * 3. Test class is injected automatically.
 */
@EnableWeld
class MyTest {

  @Inject
  Foo foo;

  @Test
  void testFooPing() {
    Assertions.assertEquals("pong", foo.ping());
  }
}

If you want to customize the configuration you would use  WeldInitiator :

@EnableWeld
class MyTest {

    @WeldSetup // This tells weld to consider only Bar, nothing else
    public WeldInitiator weld = WeldInitiator.of(Bar.class);

    @Test // Note that test method params are injected too
    public void test(Bar bar) {...}
}

If your bean is  @RequestScoped then you should activate the request context:

@EnableWeld
class MyTest {

    @WeldSetup
    public WeldInitiator weld = WeldInitiator.from(Baz.class).activate(RequestScoped.class).build();

    @Test
    public void test(Baz baz) {
      // A mocking request context is activated within the test method execution
    }
}

If your bean injects a bean you don't have an implementation, simply mock the bean:

interface Bar {
  String ping();
}

// This is the bean under the test
class Qux {
  @Inject
  Bar bar;

  String ping() {
    return bar.ping();
  }
}

@EnableWeld
class MyTest {

    @WeldSetup
    public WeldInitiator weld = WeldInitiator.from(Qux.class).addBeans(createBarBean()).build();

    static Bean<?> createBarBean() {
        return MockBean.builder()
                .types(Bar.class)
                .scope(ApplicationScoped.class)
                .creating(
                       // Mock object provided by Mockito
                       Mockito.when(Mockito.mock(Bar.class).ping()).thenReturn("pong").getMock())
                .build();
    }

    @Test
    public void test(Qux qux) {
       Assertions.assertEquals("pong", qux.ping());
    }
}

If your bean declares a  @Resource  injection point provide a mock resource, as shown below:

class Baz {

    @Resource(lookup = "somejndiname")
    String coolResource;
}

@EnableWeld
class MyTest {

    @WeldSetup
    public WeldInitiator weld = WeldInitiator.from(Baz.class).bindResource("somejndiname", "coolString").build();

    @Test
    public void test(Baz baz) {
       Assertions.assertEquals("coolString", baz.coolResource);
    }
}

NOTE: @EJB, @PersistenceContextand @PersistenceUnitinjection points are also supported.

Conclusion

We have shown that Weld and JUnit play well together. weld-junit allows you to test your CDI beans quickly and easily. If you wish to see more in-depth guide/examples, it's right inside the project. Last but not least, it's an open source project, so feel free to create issues, share ideas, throw feature requests, and send pull requests.
 

CDI Bean (software) Spring Framework JUnit unit test

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Bye Bye, Regular Dev [Comic]
  • How to Create a Real-Time Scalable Streaming App Using Apache NiFi, Apache Pulsar, and Apache Flink SQL
  • How Observability Is Redefining Developer Roles
  • A Brief Overview of the Spring Cloud Framework

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: