Title: OpenWebBeans JUnit 5 Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . https://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. # OpenWebBeans JUnit 5 OpenWebBeans provides a JUnit 5 integration. It brings an extension which will be backed by CDI Standalone Edition API (`SeContainer`). The entry point is `@Cdi` API which maps the main methods of `SeContainerInitializer`. It typically enables you to define which classes you want to deploy for the test or if you want to use classpath scanning. Here is how a test can look like: :::java @Cdi(disableDiscovery = true, classes = MyService.class) class CdiTest { @Inject private MyService service; @Test void test() { assertEquals("ok", service.ok()); } } As you may notice, this test disable the default classpath scanning and only activate `MyService` bean. Once a test is marked `@Cdi` you get injections of the underlying container available in the test class. This is how previous snippet can inject `MyService` into the test class without having anything else to do. ## Dependency :::xml org.apache.openwebbeans openwebbeans-junit5 ${owb.version} IMPORTANT: this feature comes with OpenWebBeans >= 2.0.11. ## Reusable mode `@Cdi` also adds a specific API called `reusable`. When this is set to `true`, the container is started and then reused by next test. This enables to speed up the test suite a lot when reusing the same JVM to run all tests. For example if you have these two tests: :::java @Cdi(reusable = true) class MyFirstTest { @Inject private MyService service; @Test void test() { assertEquals("ok", service.ok()); } } and :::java @Cdi(reusable = true) class MySecondTest { @Inject private MyOtherService service; @Test void test() { assertEquals("ok2", service.ok()); } } Then CDI container will be started only once. However if the first test is: :::java @Cdi(reusable = true, disableDiscovery = true, classes = MyService.class) class MyFirstTest { // .. as before } Then the second test will not have its `MyOtherService` bean since previous test will only deploy `MyService`. To avoid that it is recommended to follow these best practises: - Never mix reusable and not reusable tests in the same suite (define multiple surefire executions for example), - For reusable tests define a meta annotation which shares the configuration for all tests, this means you must have a single `reusable = true` in your whole code (per execution). To define a reusable setup you just define a new annotation decorated with `@Cdi`: :::java @Target(TYPE) @Retention(RUNTIME) @Cdi(reusable = true, disableDiscovery = true, packages = MyService.class) public @interface TestConfig { } Then your test class can look like: :::java @TestConfig class MySecondTest { @Inject private MyService service; @Test void test() { assertEquals("ok", service.ok()); } } ### Surefire For reusable mode to be efficient, it is recommended to use this surefire configuration: :::xml org.apache.maven.plugins maven-surefire-plugin ${surefire.version} 1 And here is how to define executions to mix reusable and not reusable tests - which can have a different deployment setup: :::xml org.apache.maven.plugins maven-surefire-plugin ${surefire.version} default-test true not-reusable test test **/perclass/* reusable test test **/reusable/* 1 This setup assumes not reusable tests are in a `perclass` package and reusable ones are in a `reusable` package. Alternatively you can use categories (just define markers in your test code) but this is generally less obvious to manage on the long run.