Test OSGi project with JUnit4 - osgi

I have a maven project. I created a JUnit4 test class for one of my classes using the Idea wizard.
package com.mst.ica.dao.support;
import junit.framework.TestCase;
import static org.junit.Assert.*;
public class DbNamingStandardTest extends TestCase {
}
When I tried to run my test, I got the following error in my output and nothing more.
OSGi in module 'com.mst.ica.integration.api': java.lang.NoClassDefFoundError: aQute/bnd/osgi/Builder
Does anybody know what it means and how to run my test?

You seem to be mixing JUnit 3 (TestCase) and JUnit 4 (org.junit.*).
See the osgi-test project (https://github.com/osgi/osgi-test/) which provides support libraries for testing in OSGi as well as some examples. In particular, the org.osgi.test.junit4 has a test case which runs in OSGi using JUnit 4 (either plain JUnit4 or using the vintage engine with JUnit 5).

Related

Cucumber does not work with #EnableIf annotation

I want to enable cucumber tests with #EnableIf annotation, but it is not working even if i add #EnabledIf("false")
here is the code that i use :
#EnabledIf("false")
#SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
#CucumberContextConfiguration
public class CucumberRoot {
private int port = 8080;
protected String DEFAULT_URL = "http://localhost:" + port + "/";
#Autowired
protected TestRestTemplate template;
}
for other integration tests beside cucumber i am able to use #EnableIf annotation.
Is there any way to achieve that ?
No.
https://junit.org/junit5/docs/current/user-guide/
1.1. What is JUnit 5?
Unlike previous versions of JUnit, JUnit 5 is composed of several different modules from three different sub-projects.
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
The JUnit Platform serves as a foundation for launching testing frameworks on the JVM. It also defines the TestEngine API for developing a testing framework that runs on the platform. Furthermore, the platform provides a Console Launcher to launch the platform from the command line and a JUnit 4 based Runner for running any TestEngine on the platform in a JUnit 4 based environment. First-class support for the JUnit Platform also exists in popular IDEs (see IntelliJ IDEA, Eclipse, NetBeans, and Visual Studio Code) and build tools (see Gradle, Maven, and Ant).
JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5. The Jupiter sub-project provides a TestEngine for running Jupiter based tests on the platform.
JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform.
And like JUnit Jupiter and JUnit Vintage, Cucumber is a test engine on the JUnit Platform. The annotation you are using is JUnit Jupiter annotation and can only be understood by JUnit Jupiter. Neither JUnit Vintage nor Cucumber can understand it.
However Cucumber does support OpenTest4Js TestAbortedException. So you can use a before hook to stop a scenario before any step are executed. Either by throwing the exception directly or using Assumptions from JUnit Jupiter.
#Before
public void before() {
boolean condition = // decide if tests should abort
if (condition)
throw new TestAbortedException()
}
#Before
public void before() {
boolean condition = // decide if tests should abort
Assumptions.assumeTrue(condition, "Condition not met");
}

Unit test in multi-module spring boot project

I have multi-module project with similar structure as below:
server (which includes Application Context Configuration) and other configurations
shared (Utility classes used by other modules)
service (module with various repository and services)
transaction (module which handles transaction)
I need to write test for the project but I cannot change the project structure. I created a test in my transaction module.
First I got
Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
I solved it by Creating a #Configuration file in the test folder like so
#Configuration
#ComponentScan("com.mohen")
public class TestConfig {
}
And then I used it in the #SpringBootTest(TestConfig.class) .I was able to autowire, the IDE did not show any sign of error. But when I run my tests I get NoSuchBeanDefinitionException from a different class that is trying to autowire a dependency from the service module.
How to solve these issues?
The main configuration file of the application looks like
#SpringBootApplication(scanBasePackages = "com.mohen")
#EnableScheduling
#EnableAsync
#Import(value = {SSIpFilter.class, MainConfig.class})
public class Application extends SpringBootServletInitializer {...}
The MainConfig.class contains componentScan and Import annotation.
If I try to Import the MainConfig.class in my test I get a suggestion to add a dependency to the server module, which I would not want to do.
Also the entire application uses a single property file (yml). Where should I keep my property file for the test?
EDIT
I managed to run the tests, a dataJpaTest and an integration test, but it loads the entire application context.
Now the problem is, the tests that pass normally , fail when I build my project ./gradlew clean build
I get
java.lang.NoClassDefFoundError
in some classes and
Caused by: javassist.NotFoundException
in other.
I have tried adding the javaassist library but it doesn't work.
Any idea?
I found the solution to my question. Due to the project being multi module, the classes and the packages were not being recognized by other modules.
I made a few changes in my build.gradle files of the modules.
testRuntime project(':shared')
I added the above in the dependencies and also added
jar {
enabled = true
}
bootRepackage{
enabled = false
}
The jar creates a simple non executable jar file while the bootRepackage disables the creation of an executable jar which by default is its nature.

Junit5- jupiter all tests suite #BeforeAll #AfterAll not working

The before and after methods not working in JUnitPlatform.
The code is below.
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.runner.RunWith;
#RunWith(JUnitPlatform.class)
#SelectClasses({
MyControllerTest.class
})
public class AdminAppTest {
#BeforeAll
public static void setUp() {
System.out.println("setting up");
}
#AfterAll
public static void tearDown() {
System.out.println("tearing down");
}
}
I just want to running before and after methods.
Thank you
Just came across this after running into the same problem, #AfterAll and also #AfterEach annotated methods weren't called. In my case the problem was that an incorrect import for JUnit4 sneaked into my test class, I was importing org.junit.Test instead of org.junit.jupiter.api.Test. Once I fixed this my annotated methods were happily called again.
I may cite the JUnit 5 migration tipps:
#Before and #After no longer exist; use #BeforeEach and #AfterEach instead.
#BeforeClass and #AfterClass no longer exist; use #BeforeAll and #AfterAll instead.
But these annotations should be used in your test class. The methods in your suite class will not be invoked this way. And you should be aware of the fact that suites and JUnit 5 are still work in progress (see Issue 744).
You may want to check that org.junit.jupiter:junit-jupiter-engine is in your classpath.
However, recent versions of build tools (Maven with surefire plugin, Gradle, Eclipse, IntelliJ, etc.) support junit-platform. Therefore you do not need to use JUnit4 with a backward-compatible runner.
Usually you can be in the following cases:
creating new project, in which case you can start directly using only JUnit-Jupiter (and without having JUnit4 in your classpath)
migrating a project from JUnit4 to JUnit5. Here you will want to have two engines: JUnit-Vintage, which covers retrocompatibility for existing tests using the JUnit4 API, and JUnit-Jupiter who offers more flexibility, including the composition of extensions (having Spring, Mockito and parameterized tests features at the same time for example)
Using a JUnit4 runner to run JUnit-Jupiter tests is really a corner case, when you are constrained by an environment (build tool and/or IDE) that you cannot change.
For more details, sample projects are made available by the JUnit team:
Gradle project with JUnit-Jupiter
Maven project with JUnit-Jupiter
Maven project migrating from JUnit4 to JUnit5
Hope this helps !

Test spring classes in separate gradle subproject

My project is separated into several gradle subprojects (modules). I have a module which contains several spring components/beans. I want to test these beans using junit, mockito and springboottest with features like autowired and mockbean. I am using
#RunWith(SpringJUnit4ClassRunner::class)
#SpringBootTest
annotations, but when I try to run a test I get
java.lang.IllegalStateException: Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
This happens because there is no main class (#SpringBootApplication) in this module.
One can avoid this by creating a mock main class like
#SpringBootApplication
class TestApp {
}
Is there a way to make it work without creating a mock main class?
If you want to run test in sub-module you need to define some configuration class. It can be #Configuration with #ComponentScan located in src/test/java root package of sub-module, so that it wouldn't pollute your production code.
With such test configuration, just use #SpringBootTest(classes=YourTestConfiguration.class).
Maybe you want to look at new annotation since Spring Boot 1.4.x called #TestConfiguration. That one is specifically tailored towards test only configs.

Unable to run spring-boot-test

I am new to Spring-boot.
We are trying to practice spring-boot-test by adding the following Java class in this Spring guide for testing purpose.
However, it turns out that we are not able to trigger this Java class. In other words, there is no any test result showing up in the our eclipse console.
Could someone suggest us where we do wrong?
Thanks!
GreetingControllerTest.java
package hello;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
#IntegrationTest
public class GreetingControllerTest {
private RestTemplate restTemplate = new RestTemplate();
#Test
public void testGreeting() {
System.out.println("Where is my TEST?????!!!!!!");
String url = "http://localhost:8080/greeting";
assertNotNull(restTemplate.getForObject(url, Greeting.class));
}
}
The Spring Framework does not run (trigger) tests. Rather, a testing framework like JUnit or TestNG runs tests.
Your code appears to be fine. So, assuming that the example you supplied compiles (i.e., has the correct package imports) and assuming that the #Test annotation you have declared is #org.junit.Test, then you simply need to run the test as a JUnit test.
Your IDE (e.g., Eclipse, IntelliJ, NetBeans) and build framework (e.g., Maven, Ant, Gradle) should provide support for running JUnit tests.
Regards,
Sam

Resources