Integration test with jersey and spring boot 1.4.0.RELEASE - spring-boot

I am trying to write integration test with jersey, Spring boot 1.4 and Spring data jpa.I am able to start embedded server but getting error from jersey side , any help will be appreciated.
Integration test
import static org.assertj.core.api.Assertions.assertThat;
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.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT, classes=Application.class)
public class ContactServiceIT {
#Autowired
private TestRestTemplate restTemplate;
#Autowired
private ContactDao contactDao;
#Test
public void mergeContactsTest() {
String body = this.restTemplate.getForObject("/contacts/merge", String.class);
assertThat(body).isEqualTo("contacts merged");
}
}
Contact Resource
import java.io.IOException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.springframework.beans.factory.annotation.Autowired;
#Path("/contacts")
public class ContactResource {
#Autowired
private ContactService contactService;
#GET
#Path("merge")
public Response mergeContacts() throws IOException {
contactService.mergeContacts();
return Response.status(Response.Status.CREATED)
.entity("contacts merged").build();
}
}
Stack trace:
java.lang.NoSuchMethodError: org.glassfish.jersey.CommonProperties.getValue(Ljava/util/Map;Ljavax/ws/rs/RuntimeType;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
at org.glassfish.jersey.jackson.JacksonFeature.configure(JacksonFeature.java:73) ~[jersey-media-json-jackson-2.23.1.jar:na]
at org.glassfish.jersey.model.internal.CommonConfig.configureFeatures(CommonConfig.java:680) ~[jersey-common-2.7.jar:na]
at org.glassfish.jersey.model.internal.CommonConfig.configureMetaProviders(CommonConfig.java:610) ~[jersey-common-2.7.jar:na]
at org.glassfish.jersey.server.ResourceConfig.configureMetaProviders(ResourceConfig.java:800) ~[jersey-server-2.7.jar:na]
Please let me know if I am missing something.
Thanks.

Related

RestAssured, H2, SpringBootTest Transaction Management. Persisted data not available when calling REST Interface

I wrote a simple SpringBootTest where I tried to read test data from a JSON file and insert it into the database in the #BeforeEach annotated method. When querying the data in the test method, I indeed find the data in the repository. When the REST interface is called via RestAssured and the corresponding method is executed, no data is found via the respository. However, when setting rollback=false in the test, I can find the data in the H2 database. Test code as follows:
package mypackage;
import static io.restassured.RestAssured.get;
import static org.hamcrest.Matchers.hasItems;
import static org.mockito.ArgumentMatchers.eq;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import mypackage.MessageEntity;
import mypackage.MessageRepo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
#EnableAutoConfiguration
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "spring.main.lazy-initialization=true",
"spring.datasource.url=jdbc:h2:file:C:/mydatabase", "spring.jpa.properties.hibernate.default_schema=",
"spring.jpa.hibernate.ddl-auto=create", "spring.datasource.driverClassName=org.h2.Driver",
"spring.jpa.properties.hibernate.show_sql=true", "spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect",
"spring.datasource.username=sa" })
#ActiveProfiles("test")
class MyWebServiceTest{
#Autowired
MessageRepo messageRepo;
#LocalServerPort
int port;
#Autowired
private PlatformTransactionManager platformTransactionManager;
#BeforeEach
void beforeAll() throws IOException, URISyntaxException {
RestAssured.baseURI = "http://localhost/webservice";
RestAssured.port = port;
TransactionTemplate transactionTemplate = new TransactionTemplate(this.platformTransactionManager);
final List<MessageEntity> messages = setupMessages();
transactionTemplate.execute((TransactionCallback<Object>) status -> messageRepo.saveAllAndFlush(messages));
}
#Test
#Transactional
#Rollback(false)
void test() {
System.out.println(messageRepo.findAll()); // successfully retrieves data
get("/messages").then().assertThat().body("$", hasItems(67)).and().statusCode(eq(200)); // in the corresponding method of the WebService, no data is found
}
private List<MessageEntity> setupMessages() throws IOException, URISyntaxException {
final String messagesString = Files.readString(
Paths.get(Objects.requireNonNull(MyWebServiceTest.class.getResource("/messages.json")).toURI()));
return new ObjectMapper().readValue(messagesString, new TypeReference<List<MessageEntity>>() {
});
}
}
I tried to persist the data in the #BeforeEach in different ways, tried flushing etc, but the data is not available when doing messageRepo.findAll() in the method called in the REST-Interface. I would expect the inserted data to be also available there. However, the data is available in the test method, but not at the REST endpoint.
Do you have any idea why this is happening and what I can try to get the desired result with my test data? Thanks!

Asking me for CucumberContextConfiguration when I already have

I currently working on integration testing of one the Restful APIs. I have received an exception asking me to annotate a glue class using #CucumberContextConfiguration. At the moment, I have
ApplicationTests.java
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import io.cucumber.spring.CucumberContextConfiguration;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
#RunWith(Cucumber.class)
#CucumberContextConfiguration
#SpringBootTest(classes = {VehicleRegApplication.class,
VehicleRegApplicationTests.class,
CucumberSpringConfiguration.class})
#CucumberOptions(features = "src/test/resources/Features",
glue = {"com.vehiclereg.StepDefinitions"},
plugin = {"pretty"})
public class VehicleRegApplicationTests {
#Test
void contextLoads() {
}
}
CucumberSpringConfiguration.java in the same folder as the ApplicationTests.java
import io.cucumber.spring.CucumberContextConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
#CucumberContextConfiguration
#SpringBootTest
#AutoConfigureMockMvc
public class CucumberSpringConfiguration {
}
I have cucumber-java, cucumber-spring, cucumber-junit, junit injected. I have done what the exception says and when I run the test the same error comes back.
io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class with some context configuration.
I wonder if I have done something wrong?

How to print traceId and spanId with brave tracing?

Earlier i used to write below code with spring boot 1.5.12 :-
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
#Autowired
Tracer tracer;
Span span = this.tracer.getCurrentSpan();
System.out.println(Span.idToHex(span.getSpanId()));
System.out.println(Span.idToHex(span.getTraceId()));
But this code is not working with spring boot 2.2.6 .How should i print now ?
import brave.Tracer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Slf4j
#Component
public class BravePrinter {
#Autowired
private Tracer tracer;
public void print() {
var span = this.tracer.currentSpan();
System.out.println(span.context().traceIdString());
System.out.println(span.context().spanIdString());
}
}

Spring Boot Integration Tests, #Autowired works, #Inject does not, Why?

I work on a Spring Boot application, I have written a Service and I want to test this Service in an Integration Test. Therefor I want to Inject the Service Into my test. If I use the #Inject annotation, The Service is null. If I use #Autowired, the Service gets Injected and the test works. I thought the annotation should do more or less the same, with the only differrence that #Autowired fails if no bean is available, because it is default set to required=true.The Service has an Interface and I choose the implementation based on Field Name.
Interface:
import org.springframework.core.io.ByteArrayResource;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
public interface FileService {
boolean storeDicomZip(InputStream stream, long caseId);
.
.
.
}
Implementation:
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import java.io.*;
import java.nio.file.Files;
import java.util.Optional;
#Service
public class FileSystemFileService implements FileService {
.
.
.
}
And The Test:
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.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
#IntegrationTest
public class FileSystemFileServiceTest {
#Autowired
private FileService fileSystemFileService;
#Test
public void storeDicomZip() throws Exception {
InputStream stream = new ByteArrayInputStream("TEST".getBytes());
fileSystemFileService.storeDicomZip(stream, 3);
Assert.assertTrue(fileSystemFileService.getDicomZipVersions(3) == 1);
}
.
.
.
}
As described, If I use #Autowired, like here it works, if I use #Inject it does not because fileSystemFileService is null.
Does somebody know why this is the case, and what I have to change to use #Inject?

Unable to inject dependency in Junit test

Having some trouble injecting a dependency in one of my JUnit test classes.
I believe the TestApplication is not package scanning or is not being loaded.
Code below:
package com.mitto.repositories;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.mitto.MittoApplicationTests;
import com.mitto.domain.User;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration( classes= { MittoApplicationTests.class } )
#TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class})
#DatabaseSetup("UserRepositoryTest.xml")
public class UserRepositoryTest {
#Autowired
UserRepository repository;
private static final long FACEBOOK_ID = 1234567;
#Test
public void getUserById() {
User user = repository.findOne(1L);
assertNotNull(user);
assertEquals( user.getFacebookId(), FACEBOOK_ID );
}
}
MittoApplicationTests.java
package com.mitto;
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
public class MittoApplicationTests {
#Test
public void contextLoads() {
}
}
UserRepository.java
package com.mitto.repositories;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import com.mitto.domain.User;
#Repository
public interface UserRepository extends PagingAndSortingRepository<User, Long>{
User findByFacebookId( long facebookId );
User findByAuthToken( String token );
}
I can't see anything wrong with this.
Sometimes, a working example is better than fixes.
Here is a working example:
First, in your configuration class
#SpringBootApplication
#ComponentScan(value = "com.mitto")
#EnableJpaRepositories(value = "com.mitto")
#EntityScan(basePackages = {"com.mitto.domain"}, basePackageClasses = {Jsr310JpaConverters.class})
public class MittoApplicationTests {
}
Second, in your test class
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = MittoApplicationTests.class) // replace the #ContextConfiguration with #SpringBootTest
// rest of of your annotations ...
public class UserRepositoryTest {
#Autowired
UserRepository repository;
// your test cases
}
A Spring Boot application is just a Spring ApplicationContext, so nothing very special has to be done to test it beyond what you would normally do with a vanilla Spring context. One thing to watch out for though is that the external properties, logging and other features of Spring Boot are only installed in the context by default if you use SpringApplication to create it.
Spring Boot provides a #SpringBootTest annotation which can be used as an alternative to the standard spring-test #ContextConfiguration annotation when you need Spring Boot features. The annotation works by creating the ApplicationContext used in your tests via SpringApplication.
Please read the documentation for more details:
SpringBootTest annotation
boot-features-testing

Resources