JUnit 5 and Spring Framework 4.3.x - spring

Is it right, that JUnit 4.12 and junit-vintage-engine (from JUnit 5) can be used together with Spring Framework 4.3.x?
Is there a possibility to also use junit-jupiter-api and junit-jupiter-engine (both from JUnit 5)?

I assume you mean Spring integration tests, something like:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest(classes = Application.class)
public class ExampleIT {
#Test
public void test() {
}
}
This can be run with the vintage engine.
You can also use JUnit 5 with Spring 4.3 using the prototype for Spring 5. The Jars are available on Jitpack, so in order to convert this test to JUnit 5 just add the Jupiter API and the prototype to your dependencies, e.g. for maven
<dependency>
<groupId>com.github.sbrannen</groupId>
<artifactId>spring-test-junit5</artifactId>
<version>1.0.0.M3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.0.0-M3</version>
<scope>test</scope>
</dependency>
...
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
And instead of the SpringRunner use the SpringExtension and the JUnit jupiter API:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
#ExtendWith(SpringExtension.class)
#SpringBootTest(classes = Application.class)
public class ExampleIT {
#Test
public void test() {
}
}
Hope this helps

Related

Required: Definitive Annotations and pom dependencies to test Apache Camel with Spring Boot and Java Config

I'm going round in circles with this one.
Because it uses Spring Test and Java Config, I copied the simple FilterTest example from here, which worked OK as was.
But as soon as I added an #Autowired field, I got an UnsatisfiedDependencyException [Unsatisfied dependency expressed through field ... No qualifying bean of type ... available].
After fixing that I now get a NullPointerException on resultEndpoint.expectedBodiesReceived(expectedBody); in the first #Test method. When this happens, there is absolutely no output in the console, so evidently Spring hasn't even started.
Here's the slightly modified test class:
package org.apache.camel.spring.javaconfig.patterns;
import org.apache.camel.EndpointInject;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.spring.javaconfig.SingleRouteCamelConfiguration;
import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import c10y.camel.converter.QbInvoiceConverter;
/**
* Tests filtering using Spring Test and Java Config
* page: https://camel.apache.org/manual/latest/testing.html
* code: https://github.com/apache/camel/blob/master/core/camel-core/src/test/java/org/apache/camel/processor/FilterTest.java
*/
#CamelSpringBootTest
#ContextConfiguration
#DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)
public class FilterTest {
#EndpointInject("mock:result")
protected MockEndpoint resultEndpoint;
#Produce("direct:start")
protected ProducerTemplate template;
#Autowired
private QbInvoiceConverter converter;
#Test
public void testSendMatchingMessage() throws Exception {
String expectedBody = "<matched/>";
resultEndpoint.expectedBodiesReceived(expectedBody);
template.sendBodyAndHeader(expectedBody, "foo", "bar");
resultEndpoint.assertIsSatisfied();
}
#Test
public void testSendNotMatchingMessage() throws Exception {
resultEndpoint.expectedMessageCount(0);
template.sendBodyAndHeader("<notMatched/>", "foo", "notMatchedHeaderValue");
resultEndpoint.assertIsSatisfied();
}
#Configuration
public static class ContextConfig extends SingleRouteCamelConfiguration {
#Bean
public RouteBuilder route() {
return new RouteBuilder() {
public void configure() {
from("direct:start")
.filter(header("foo")
.isEqualTo("bar"))
.to("mock:result")
;
}
};
}
}
}
I have tried to bring this up to date with the migration instructions here. Briefly, this states:
Migration steps linked to JUnit 5 support in Camel Test itself should have been applied first
Imports of org.apache.camel.test.spring.* should be replaced with org.apache.camel.test.spring.junit5.*
Usage of #RunWith(CamelSpringRunner.class) should be replaced with #CamelSpringTest
Usage of #BootstrapWith(CamelTestContextBootstrapper.class) should be replaced with #CamelSpringTest
Usage of #RunWith(CamelSpringBootRunner.class) should be replaced with #CamelSpringBootTest
The other part of my question relates to having the correct dependencies in pom.xml. I'm learning Camel from Camel in Action E2, so my pom has test dependencies from the book as well as others I have picked up on the way; so there may be clashes or incompatibilities in there:
<!-- from .../camel-in-action-2/chapter9/spring-boot-test-one-route/pom.xml -->
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test</artifactId>
<scope>test</scope>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring</artifactId>
<scope>test</scope>
</dependency>
<!-- from elsewhere -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring-junit5</artifactId>
<scope>test</scope>
</dependency>
I'm using Apache Camel 3.4.0 LTS and Spring Boot 2.3.0.RELEASE.
As the title to this question states, I'd really like to have the definitive annotation and pom configuration to allow me to simply get on with creating test routes to unit test my Components, Converters, and so forth [without tearing my hair out!].
PS: What's the difference between org.junit.Test and org.junit.jupiter.api.Test annotations, and when should you use one over the other?

Can't run JUnit test with Spring

I have a test class looking like this:
#RunWith(SpringRunner.class)
#SpringBootTest
public class myTests {
#Autowired
private MyComponent myComponent;
#Test
public void test1() { ... }
}
I get an initialization error and an exception:
java.lang.Exception: No tests found matching...
Take a look at your imports; for your code to work in the way you intend it to, your imports should include:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
but depending on how your IDE is configured you can sometimes end up with a different version of junit by default which doesn't play nicely with Spring Boot.
If the above imports don't work for you you may need to add the following maven dependency to your pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletException

when i am trying to run the controller Testing in Spring-boot version 1.5.3 Release using the Spring-Boot-Test I am geting the Error Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletException
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;
import com.hanselnpetal.domain.CustomerContact;
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
#AutoConfigureMockMvc
public class ContactsManagementControllerIntegrationTest {
#Autowired
ContactsManagementController contactsManagementController;
#Test
public void testAddContactHappyPath() {
CustomerContact aContact = new CustomerContact();
aContact.setFirstName("Jenny");
aContact.setLastName("Johnson");
// POST our CustomerContact form bean to the controller; check the outcome
String outcome = contactsManagementController.processAddContactSubmit(aContact);
// Assert THAT the outcome is as expected
assertThat(outcome, is(equalTo("success")));
}
}
I am running the class ContactsManagementControllerIntegrationTest.java using (eclipse) the right click on the file and run as junit . any help appreciated.
Ensure that you have below dependency in your pom.xml (maven)
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>

Spring MockMvc trimming parameter

I have run into a problem that has me stumped. I am running the latest version of Spring and JUnit. I was experimenting with the MockMvc and Spring integration test classes in order to see if it would fit my companies needs and it was working well, until I tried to submit a request for that contained a #PathVariable which is a version number in the url.
Pom;
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
</parent>
<groupId>asd</groupId>
<artifactId>asd</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>asd</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.1.6.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Example Controller;
import junit.framework.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ExampleController {
#RequestMapping(value = "/example/appVersion/{applicationVersion}")
public #ResponseBody void example(#PathVariable("applicationVersion") String applicationVersion) {
if (!"1.0.0.0".equals(applicationVersion)) {
Assert.fail("I needed to be 1.0.0.0");
}
}
}
Test Class;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.web.context.WebApplicationContext;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath*:appContext.xml")
#WebIntegrationTest
public class ExampleProblem {
#Autowired
WebApplicationContext context;
#Test
public void test() throws Exception {
String url = "/example/appVersion/1.0.0.0";
// String url = "/example/appVersion/{applicationVersion}";
//#formatter:off
MvcResult result = webAppContextSetup(context)
.build()
.perform(
get(url)
// get(url, "1.0.0.0")
.accept("application/json")
).andDo(print())
.andExpect(status().is(200))
.andReturn();
//#formatter:on
Assert.assertNotNull(result);
}
}
My appContext.xml file only contains this line (other than the initial beans tag and end tag);
<context:component-scan base-package="asd" />
When I view the request coming into my example controller, I can see with the debugger it says /example/appVersion/1.0.0.0 but the path variable is being set to "1.0.0" always. It appears the last .0 is always being dropped because if I pass in "1.0.0.0.0" it trims to the expected "1.0.0.0".
Any insight into what may be causing this or what I am doing wrong would be greatly appreciated.
Thank you.
This happens because Spring interprets the last dot (.) and following characters as a file extension.
In order to fix this, you need to tell Spring that the parameter expects dot characters by adding ":.+" to the end of the controller parameter.
So the annotation now looks like this;
#RequestMapping(value = "/example/appVersion/{applicationVersion:.+}")

Spring Framework: Failed to load ApplicationContext

While running script in Spring framework it is throwing error message as "Failed to load ApplicationContext". I have my ApplicationContext.xml file under src/test/resources
And i was using
#RunWith(value = Parameterized.class)
public class CustomerTest extends FunctionLibrary { ... }
After some suggestions from forum i used
#RunWith(value = Parameterized.class)
#ContextConfiguration(locations = "file:src/test/resources/applicationContext.xml")
public class CustomerTest extends FunctionLibrary { ... }
Still i am getting the same error message. Please anyone tell me how to resolve this issue?
Thanks,
Sudhansu
There are several problems
1) use #RunWith(SpringJUnit4ClassRunner.class)
2) Your path sounds like you have a maven project. In a maven project, src/test/resources will be added to the classpath when the tests run. So use:
#ContextConfiguration(locations = "classpath:applicationContext.xml")
If you haven an other file in src/main/resources withe the same name, then I recommend to rename the one in src/test/resources to test-applicationContext.xml and then use #ContextConfiguration(locations = "classpath:test-applicationContext.xml"), just to reduce the the number of knot in your brain
Complete example:
package com.test.service;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classpath:test-ApplicationContext.xml)
public class WhateverTest {
...
}
pom excerpt:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.6.RELEASE</version>
</dependency>

Resources