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 Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Functional Endpoints: Alternative to Controllers in WebFlux
  • Mastering Unit Testing and Test-Driven Development in Java
  • Comprehensive Guide to Unit Testing Spring AOP Aspects
  • Hints for Unit Testing With AssertJ

Trending

  • Mocking Kafka for Local Spring Development
  • Ingesting Fixed-Width Mainframe Files Into Delta Lake: The Details Nobody Writes Down
  • Rethinking Java CRUDs With Event Sourcing and CQRS Patterns
  • Lambda-Driven API Design: Building Composable Node.js Endpoints With Functional Primitives
  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.

By 
Matěj Novotný user avatar
Matěj Novotný
·
Martin Kouba user avatar
Martin Kouba
·
Jan. 25, 18 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
45.5K 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.

Related

  • Functional Endpoints: Alternative to Controllers in WebFlux
  • Mastering Unit Testing and Test-Driven Development in Java
  • Comprehensive Guide to Unit Testing Spring AOP Aspects
  • Hints for Unit Testing With AssertJ

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook