DZone
Performance Zone
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
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Performance Zone > 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 · Performance Zone · Tutorial
Like (4)
Save
Tweet
36.36K 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

  • How to Translate Value to Executives Using an Outcome-Driven Mindset
  • Remote Debugging and Developer Observability
  • Flask vs. Django: Which Python Framework to Choose?
  • Testing Your Infrastructure as Code Using Terratest

Comments

Performance Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • 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:

DZone.com is powered by 

AnswerHub logo