How to Test a Spring Boot 1.2.7 Application? - java

I need to test old Spring Boot Java application (version of Spring Boot 1.2.7, Java 1.8) and I don't want to change Spring version (because the application is very voluminous and then I will have to refactor the code very much).
I'd like to apply to input of my desktop application different table column types and test that application determines them correctly.
But the problem is that due to old version of Spring I can't pull up annotations like #ExtendWith(SpringExtension.class), #ExtendWith(MockitoExtension.class), or #RunWith(SpringRunner.class) to enable spring boot features, or #SpringBootTest to load complete application context for end-to-end integration testing.
I'm using the following dependencies for tests:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
I tried to upgrade the version of Spring dependencies for testing (to be able to include annotations) and keep the Spring version of existing project but then initialization errors occured.
How can I enable spring boot features for testing?

The most recommended solution would be to upgrade the entire project. If not, the easiest solution is to rely on spring-boot-starter-test:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
This means you'll have to rely on JUnit 4 and older versions of Mockito, AssertJ and the Spring testing library.
These are the annotations you can use:
#ExtendWith(SpringExtension.class) / #RunWith(SpringRunner.class) → #RunWith(SpringJUnit4ClassRunner.class)
#ExtendWith(MockitoExtension.class) → #RunWith(MockitoJUnitRunner.class)
#SpringBootTest → #SpringApplicationConfiguration (not an exact replacement)
Test slices (#DataJpaTest, #WebMvcTest) were introduced in Spring boot 1.4, so you can't rely on those either.
The best way to find out what is possible, is by checking the reference documentation of Spring boot 1.2.7.
One example they show is:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class CityRepositoryIntegrationTests {
#Autowired
CityRepository repository;
// ...
}

Related

Why do I receive fails when I try to run my framework? [duplicate]

Im having issues running a feature in Cucumber, the feature is very basic as it's from a tutorial.
It is not defined and is as follows:
Feature: Proof that my concept works
Scenario: My first test
Given this is my first step
When this is my second step
Then this is my final step
My Cucumber runner class is as follows:
package cucumber;
import org.junit.runner.RunWith;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#Cucumber.Options(
format = {"pretty", "json:target/"},
features = {"src/cucumber/"}
)
public class CucumberRunner {
}
Also the external .jar files that I have in the project are as follows:
The exception that I'm getting is:
Exception in thread "main" cucumber.runtime.CucumberException: Failed
to instantiate public
cucumber.runtime.java.JavaBackend(cucumber.runtime.io.ResourceLoader)
with [cucumber.runtime.io.MultiLoader#75d837b6]
I've tried to look around online for the solution to this problem but have not had any luck.
I've also discussed with the OP of the tutorial and I'm still awaiting feedback but it has been a while.
I ran into a similar issue and got the same error as you did.
Firstly mention the path to the feature file
features = {"src/cucumber/myfile.feature"}
Anyway, that didn't cause the error.
To just run your Cucumber runner class, all the dependencies you need are
cucmber-junit
cucumber-java and
junit.
I had an additional cucumber-guice which was creating the problem and once I removed it, the error went away and runner was executed successfully.
From the link to the image you have mentioned it looks like you are not using cucumber-guice but still I would recommend you remove other unnecessary cucumber dependencies and try again.
1, I ran into this too few days ago, its simple just remove cucumber-Spring from the dependency.
2 If that doesn't work try updating cucumber-core, cucumber-junit, and cucumber-java all version 1.2.3
I believe the issue is that many of the cucumber add-ins, such as cucumber-testng, cucumber-spring, and (in my case) cucumber-guice, expect the corresponding module they link to be included as well. But apparently the cucumber experts decided not to include this dependency in their pom.xml files, so the problem doesn't manifest itself until runtime.
So (to answer Eugene S's question under LING's answer) if you want to actually use guice with cucumber, you need to also add guice itself as a dependency.
This worked for me, I hope it will work for you as well.
Update your Cucumber dependencies in pom.xml
i.e
cucumber-java (1.2.2)
cucumber-jvm (1.2.2)
cucumber-junit (1.2.2)
And update your Junit dependency as well. (4.11).
The only reason for this error is the version of all the cucumber libraries are not same. It should be like this:
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java8</artifactId>
<version>4.2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-picocontainer -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-testng -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>4.2.6</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
First Thing : We would request you to use Cucumber v >=4.0.0 as you are using pretty old dependency(v1.2.5) of Cucumber.
Key Point : We shall not mix direct & transitive dependencies specially their versions! Doing so can cause unpredictable outcome.
Solution: Please remove. cucumber-core, cucumber-java, cucumber-jvm-deps, gherkin and cucumber-html. They're transitive dependencies and will be provided by your direct dependencies.
You can add below set of cucumber minimal dependencies.
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.2.6</version>
<scope>test</scope>
</dependency>
After spending a lot of time on this issue, most of the errors I was receiving were due to dependencies and dependencies versions mismatch. Adding these dependencies to pom.xml file worked for me:
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-scala_2.11</artifactId>
<version>4.7.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-jvm -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm</artifactId>
<version>4.8.1</version>
<type>pom</type>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-junit -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java8 -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java8</artifactId>
<version>4.8.1</version>
</dependency>

Import Kafka MockAdminClient for unit testing my Kafka application using maven

I would like to use MockAdminClient for unit testing my Kafka application. How can I make MockAdminClient imported using maven?
https://github.com/apache/kafka/blob/2.3.0/clients/src/test/java/org/apache/kafka/clients/admin/MockAdminClient.java
UPDATE:
My kafka-client related pom.xml
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>${kafka.version}</version>
</dependency>
By referring test by maven I found sth like this
How can I reference unit test classes of a maven dependency in my java project?
You need to pull the test classifier, and then add the test scope to get it only available for your unit tests
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>${kafka.version}</version>
<scope>test</scope>
<classifier>test</classifier>
</dependency>
It is a part of Kafka Clients, you have to add the following dependency in maven pom.xml.
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.3.0</version>
</dependency>
For more dependencies, you can refer the below link.
https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients

Spring Reactive Test case fails to start the Netty Server

I have spring test-case as shown below when I run it is not starting the Netty server and provides following exception.
Caused by: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155)
Below is my test case:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SpringWebFluxDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class CustomPriceControllerTest {
#Autowired
private ApplicationContext context;
private WebTestClient testClient;
#Before
public void init() {
testClient = WebTestClient.bindToApplicationContext(context).configureClient().baseUrl("http://localhost:8080").responseTimeout(Duration.ofSeconds(30)).build();
}
#Test
public void broadcastVoltageConsumption() {
this.testClient.get().uri("/api/getCustomPrice")
.accept(MediaType.APPLICATION_STREAM_JSON)
.exchange()
.expectBodyList(Custom.class)
.consumeWith((customResults) -> {
List<Custom> list = CustomResults.getResponseBody();
Assert.assertTrue(list != null && list.size() > 0);
});
}
}
My pom.xml has excluded the dependency for tomcat to enable Netty. My Spring boot class works perfectly fine. It boots Netty server.
Update - pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Had to add javax.servlet-api because I was facing issues with javax.servlet-api missing.
Update - 2
Removing the javax.servlet dependency from pom.xml solves the issue.
While when I try to run my main application it starts the Netty server normally. What is missing in this configuration? Can anyone help on this?
You wanted the webserver to be powered by Netty, but the exception you are getting is Servlet Specific
Since Netty is not servlet based technology, it seems you that somewhere (gradle/maven/#Configuration) you are mixing them,
so , just remove all references to Servlet dependencies and re try
If any dependency needs a servlet, it will force Jetty to come up and netty will never start in that case.
Whenever you see webflux is starting Jetty and not netty, you should run following command and then search who is including Jetty as dependency then you will find the answer.
./gradlew dependencies
In your case, you are including servlet dependency directly which is causing that issue.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
I had the same issue. I just remove this dependency (which have servlet dependency):
testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')

What is the difference between the various Spring Data Rest artifactids?

I am specifically talking about the following.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<version>2.5.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-core</artifactId>
<version>2.5.4.RELEASE</version>
</dependency>
The documentation here isn't very clear on the differences between spring-boot-starter-data-rest and spring-data-rest-webmvc. Is the difference essentially just the spring boot auto-configuration being included in the spring-boot-starter-data-rest artifact?
I assume that they both would include spring-data-rest-core at some point? How do I know which version of Spring Data REST WebMVC I would be using with spring-boot-start-data-rest?
I found this similar question but doesn't directly answer my question.

What Jersey dependency to add to avoid NoClassDefFoundError for jersey.repackaged.com.google.common.collect.Maps

I'm trying to run a a test that extends JerseyTest but when running it I'm getting a:
java.lang.NoClassDefFoundError: jersey/repackaged/com/google/common/collect/Maps
Any idea what dependency I'm missing? I've included the following jersey artifacts in my pom.xml and jersey.version is 2.5.1:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>1.18</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
You'll need:
<dependency>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
<version>2.6</version>
</dependency>
From http://blog.dejavu.sk/2014/02/21/jersey-2-6-has-been-released-new-and-noteworthy/
Jersey, from versions 2.6 for JAX-RS 2.0 and 1.18.1 for JAX-RS 1.1, no longer transitively brings Guava and ASM libraries to your application. This means that even when we still use them internally you can use different versions of these libraries. Classes from both of these libraries has been repackaged, jersey.repackaged.com.google.common and jersey.repackaged.objectweb.asm respectively, and shrinked to lower the footprint. ASM 5 is now part of jersey-server core module and for Guava we’ve created a separate bundle module jersey-guava as this dependency is widely used in multiple Jersey modules.
You're using the Jersey 2.6 jersey-test-framework-provider-grizzly2.

Categories