Why is my spring boot controller not auto-wiring the Validator? - java

I have a controller with the following:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import javax.validation.Validator;
#RestController
#RequestMapping("/")
public class MyController {
#Autowired
private Validator validator;
//..elided...
#GetMapping
public String getSomething(#Valid #RequestBody MyRequest) {
//This is null
if ( validator == null ) {
throw new Exception("is null");
}
}
}
My configuration class:
package com.app.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#EnableWebMvc
#ComponentScan("com.app")
public class ValidationConfig {
#Bean
public Validator validator() {
return new LocalValidatorFactoryBean();
}
/* //Including this doesn't help
#Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
return methodValidationPostProcessor;
}*/
}
Gradle:
buildscript {
ext {
springBootVersion = "1.5.6.RELEASE"
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: "java"
apply plugin: "eclipse"
apply plugin: "org.springframework.boot"
apply plugin: "idea"
apply plugin: "jacoco"
jar {
baseName = "my-service"
version = "0.0.1-SNAPSHOT"
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
//Spring Boot
compile("org.springframework.boot:spring-boot-starter")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")
//Testing
testCompile("org.hamcrest:hamcrest-all:1.3")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
No matter what I do, the validator in my controller is null!

In your controller you are expecting a javax.validation.Validator but in the config you are using org.springframework.validation.Validator

Related

Telegram bot does not working via webhook in Java

I'm creating telegram-bot. When I use longpolling-bot it works correct, but I can't create bot that works on webhooks - http-request don't reach endpoint that has been registered as webhook-url in telegram.
For local deployment I use ngrok application.
I'm trying to send POST-request using Postman, which simulates an http-request from telegram-server, but the requests don't reach the method org.telegram.telegrambots.updatesreceivers.RestApi::updateReceived
This is the code:
build.gradle
plugins {
id "java"
id "org.springframework.boot" version "3.0.1"
id "io.spring.dependency-management" version "1.1.0"
}
repositories {
mavenCentral()
mavenLocal()
}
group 'com.example'
sourceCompatibility = JavaVersion.VERSION_17
def telegramBotVersion = "6.3.0"
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter'
implementation "org.telegram:telegrambots-spring-boot-starter:$telegramBotVersion"
implementation "org.telegram:telegrambotsextensions:$telegramBotVersion"
implementation 'javax.ws.rs:javax.ws.rs-api:2.0-m08'
implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
}
package com.example.telegram.bot;
import com.example.telegram.service.TelegramService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.telegram.telegrambots.extensions.bots.commandbot.TelegramWebhookCommandBot;
import org.telegram.telegrambots.meta.api.objects.Update;
#Slf4j
public class WebhookBot extends TelegramWebhookCommandBot {
private final String name;
private final String token;
public WebhookBot(String name, String token) {
this.name = name;
this.token = token;
}
#Autowired
private TelegramService telegramService;
#Override
public String getBotUsername() {
return name;
}
#Override
public String getBotToken() {
return token;
}
#Override
public String getBotPath() {
return "webhookurl";
}
#Override
public void processNonCommandUpdate(Update update) {
System.out.println("processNonCommandUpdate");
}
}
package com.example.telegram.config;
import com.example.telegram.bot.WebhookBot;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.telegram.telegrambots.bots.TelegramWebhookBot;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.api.methods.updates.SetWebhook;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import org.telegram.telegrambots.updatesreceivers.DefaultWebhook;
#Configuration
#Profile("webhook")
#Slf4j
public class WebHookBotConfig {
#Value("${telegram.bot.name}")
private String name; //bot-name
#Value("${telegram.bot.token}")
private String token; //bot-token
#Value("${telegram.bot.webhook.uri}")
private String webhookUri; // https://7b66-188-130-157-6.eu.ngrok.io/ for example
#Value("${telegram.bot.webhook.internalUrl}")
private String internalWebServerUrl; // http://localhost:8080
#Bean
public TelegramWebhookBot telegramWebhookBot() throws TelegramApiException {
DefaultWebhook defaultWebhook = new DefaultWebhook();
defaultWebhook.setInternalUrl(internalWebServerUrl);
TelegramBotsApi botsApi = new TelegramBotsApi(DefaultBotSession.class, defaultWebhook);
WebhookBot telegramBot = new WebhookBot(name, token);
SetWebhook setWebhook = new SetWebhook();
setWebhook.setUrl(webhookUri);
botsApi.registerBot(telegramBot, setWebhook);
return telegramBot;
}
}
./ngrok http 8080

Duplicated Header in Response from Spring Boot RESTful App

I've seen this question a few times but nothing seems to quite line up with how we have our app set-up, so I'm asking it.
build.gradle (using gradle 7.1.1)
plugins {
id 'org.springframework.boot' version '2.5.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'war'
id 'groovy'
id 'idea'
}
group = 'com.dcblox'
version = '0.0.2-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://dl.bintray.com/epam/reportportal" }
maven { url "https://m2proxy.atlassian.com/repository/public" }
}
configurations {
providedRuntime
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-configuration-processor'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.springframework:spring-test'
testImplementation 'cglib:cglib-nodep:3.3.0'
testImplementation 'org.objenesis:objenesis:3.2'
implementation 'org.jetbrains:annotations:21.0.1'
testImplementation 'org.codehaus.groovy:groovy-all:3.0.8'
testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0'
testImplementation 'junit:junit:4.13.2'
}
compileJava {
options.annotationProcessorPath = configurations.annotationProcessor
}
war {
enabled = true
}
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
}
}
WebConfig.java
#Configuration
#ComponentScan("com.acme.services.authenticate.interceptor")
public class WebConfig implements WebMvcConfigurer {
#Value("${APIURL}")
private String APIURL;
#Value("${environment}")
String environment;
private static final String SWAGGER_API_VERSION = "1.0";
private static final String title = "REST API";
private static final String description = "RESTful API";
#Autowired
AuthenticateInterceptor authenticateInterceptor;
List<String> excludeURLs = new ArrayList<>();
#Override
public void addInterceptors(InterceptorRegistry registry) {
excludeURLs.add("/webjars/**");
excludeURLs.add("/authenticate/secondfactor");
excludeURLs.add("/authenticate/requestSecondFactor");
excludeURLs.add("/authenticate/login");
excludeURLs.add("/user/newuserreset");
excludeURLs.add("/user/admin/**");
excludeURLs.add("/storage/admin");
excludeURLs.add("/datacenter/**");
excludeURLs.add("/storage/admin/**");
excludeURLs.add("/user/passwordurl");
excludeURLs.add("/user/forgotpassword");
excludeURLs.add("/payment/");
excludeURLs.add("/organization/admin");
excludeURLs.add("/attachment/admin/**");
excludeURLs.add("/documents/**");
excludeURLs.add("/sign/**");
excludeURLs.add("/organization/organizations/**");
if(!environment.contains("prod")){
excludeURLs.add("/authenticate/login/test");
}
registry.addInterceptor(authenticateInterceptor).excludePathPatterns(excludeURLs);
}
#Bean
CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
return filter;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
WebSecurityConfig.java
package com.acme.services.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import java.util.stream.Stream;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${app.allowedOrigins}")
private String[] allowedOrigins;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests ->
authorizeRequests.anyRequest().authenticated()
)
.cors()
.configurationSource(corsConfigSource())
.and()
.csrf().disable();
}
private CorsConfigurationSource corsConfigSource() {
final CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.addAllowedHeader(CorsConfiguration.ALL);
corsConfig.addAllowedMethod(CorsConfiguration.ALL);
corsConfig.setAllowCredentials(true);
corsConfig.setMaxAge(1800L);
Stream.of(allowedOrigins).forEach(
origin -> corsConfig.addAllowedOriginPattern(origin)
);
return request -> corsConfig;
}
}
application.yml
app:
name: middleware
allowedOrigins: "http://127.0.0.1:8080,http://127.0.0.1:3000,http://10.1.143.100:8080,https://www.acme.com"
environment: development
server:
servlet:
session:
cookie:
path: /
Notes:
We do not use the #CrossOrigin annotations in the controllers or the controller methods.
There are no filters or #Components implementing the Filter class
This screenshot shows the response headers
I may be missing something to others to help figure out what might be the source of the issue, and if so let me know and I'll post it.
I know something has to be getting loaded twice but for the life of me I can not figure out what.
Any help is appreciated

JUnit testcases is throwing NoClassDefFoundError

I am trying to executing basic testcase, which I have completed doing setup and I am getting below error:
java.lang.NoClassDefFoundError: org/junit/platform/engine/EngineDiscoveryListener
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.getLauncherDiscoveryListener(LauncherDiscoveryRequestBuilder.java:241)
at org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.build(LauncherDiscoveryRequestBuilder.java:235)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.createUnfilteredTest(JUnit5TestLoader.java:75)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.createTest(JUnit5TestLoader.java:66)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.loadTests(JUnit5TestLoader.java:53)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:526)
Find below my ConfigServer class:
package org.siaa.devops;
import java.util.Hashtable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.config.server.EnableConfigServer;
import com.jcraft.jsch.JSch;
#SpringBootApplication
#EnableConfigServer
public class ConfigServer extends SpringBootServletInitializer {
private static final String PREFERRED_AUTENTICATION_MODE = "publickey";
public static void main(String[] args) {
// Hack in JSCH to avoid interactive session
// Override PreferredAuthentications in JSCH
Hashtable<String, String> config = new Hashtable<String, String>();
config.put("PreferredAuthentications", PREFERRED_AUTENTICATION_MODE);
JSch.setConfig(config);
SpringApplication.run(ConfigServer.class, args);
}
#Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder application) {
return application.sources(ConfigServer.class);
}
}
build.gradle
group 'org.siaa.develop'
buildscript {
ext {
//springBootVersion = '1.5.4.RELEASE'
//springBootVersion = '2.0.6.RELEASE'
springBootVersion = '2.2.6.RELEASE'
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: "io.spring.dependency-management"
apply plugin: 'org.springframework.boot'
apply plugin: 'java'
apply plugin: 'eclipse'
//version = '0.0.1-SNAPSHOT'
//springBoot {
//executable = true
//}
bootJar {
launchScript()
}
ext {
springCloudVersion = 'Hoxton.SR3'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
//mavenCentral()
maven {
url 'http://artifactory.siaa.org/artifactory/siaa-mp-develop'
}
}
dependencies {
compile('org.springframework.cloud:spring-cloud-config-server:2.2.2.RELEASE')
compile('org.springframework.boot:spring-boot-starter-actuator:2.2.6.RELEASE')
compile('org.springframework.cloud:spring-cloud-security:2.2.1.RELEASE')
testCompile('org.springframework.boot:spring-boot-starter-test')
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
//Kafka and spring cloud config monitor
compile('org.springframework.cloud:spring-cloud-starter-bus-kafka:2.0.0.RELEASE')
compile('org.springframework.cloud:spring-cloud-config-monitor:2.2.1.RELEASE')
//Prometheus
compile('io.micrometer:micrometer-registry-prometheus')
implementation("org.junit.jupiter:junit-jupiter:5.6.0")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
Added testcase is ConfigServerTest
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 ConfigServerTest {
#Test
public void contextLoads() {
}
}
I have done research and same code seems to working fine in other machine but causing issue in my local.
Unable to fix it. Please help me out with it.
Gradle version I am using is: Gradle-6.5.1
Java (JRE)version :1.8.0_40
Thanks in advance.

Tests do not run using Spring WebFlux & Reactive MongoDB

I am learning Spring Boot, and am working with Spring WebFlux, and reactive Mongo DB. My controllers are working fine, but my tests are failing on null pointer exception.
My build.gradle is:
plugins {
id 'org.springframework.boot' version '2.4.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'guru.springframework'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'junit:junit:4.12'
compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
testCompileOnly 'org.projectlombok:lombok:1.18.16'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
//testCompile group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '3.0.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
test {
useJUnitPlatform()
}
My Controller is:
package guru.springframework.spring5webfluxrest.controllers;
import guru.springframework.spring5webfluxrest.domain.Category;
import guru.springframework.spring5webfluxrest.repositories.CategoryRepository;
import org.reactivestreams.Publisher;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.concurrent.Flow;
#RestController
public class CategoryController {
private final CategoryRepository categoryRepository;
public CategoryController(CategoryRepository categoryRepository) {
this.categoryRepository = categoryRepository;
}
#GetMapping("/api/v1/categories")
public Flux<Category> list(){
return categoryRepository.findAll();
}
#GetMapping("/api/v1/categories/{id}")
public Mono<Category> getById(#PathVariable String id){
return categoryRepository.findById(id);
}
#ResponseStatus(HttpStatus.CREATED)
#PostMapping("/api/v1/categories")
public Mono<Void> create(#RequestBody Publisher<Category> categoryStream){
return categoryRepository.saveAll(categoryStream).then();
}
#PutMapping("/api/v1/categories/{id}")
public Mono<Category> update (#PathVariable String id, #RequestBody Category category){
category.setId(id);
return categoryRepository.save(category);
}
#PatchMapping("/api/v1/categories/{id}")
public Mono<Category> patch(#PathVariable String id, #RequestBody Category category){
Category foundCategory = categoryRepository.findById(id).block();
if(category.getDescription() != foundCategory.getDescription()){
foundCategory.setDescription(category.getDescription());
return categoryRepository.save(foundCategory);
}
return Mono.just(foundCategory);
}
}
My test is:
package guru.springframework.spring5webfluxrest.controllers;
import guru.springframework.spring5webfluxrest.domain.Category;
import guru.springframework.spring5webfluxrest.repositories.CategoryRepository;
import org.junit.Before;
import org.junit.Test;
//import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import org.mockito.Mockito;
import org.reactivestreams.Publisher;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
public class CategoryControllerTest {
WebTestClient webTestClient;
CategoryRepository categoryRepository;
CategoryController categoryController;
#Before
public void setUp() throws Exception {
categoryRepository = Mockito.mock(CategoryRepository.class);
categoryController = new CategoryController(categoryRepository);
webTestClient = WebTestClient.bindToController(categoryController).build();
}
#Test
public void list() {
given(categoryRepository.findAll())
.willReturn(Flux.just(Category.builder().description("Cat1").build(),
Category.builder().description("Cat2").build()));
webTestClient.get()
.uri("/api/v1/categories/")
.exchange()
.expectBodyList(Category.class)
.hasSize(2);
}
#Test
public void getById() {
given(categoryRepository.findById("someid"))
.willReturn(Mono.just(Category.builder().description("Cat").build()));
webTestClient.get()
.uri("/api/v1/categories/someid")
.exchange()
.expectBody(Category.class);
}
#Test
public void create() {
given(categoryRepository.saveAll(any(Publisher.class)))
.willReturn(Flux.just(Category.builder().description("descrp").build()));
Mono<Category> catToSaveMono = Mono.just(Category.builder().description("Some Cat").build());
webTestClient.post()
.uri("/api/v1/categories")
.body(catToSaveMono, Category.class)
.exchange()
.expectStatus()
.isCreated();
}
#Test
public void update() {
given(categoryRepository.save(any(Category.class)))
.willReturn(Mono.just(Category.builder().build()));
Mono<Category> catToUpdateMono = Mono.just(Category.builder().description("Some Cat").build());
webTestClient.put()
.uri("/api/v1/categories/asdfjkl")
.body(catToUpdateMono, Category.class)
.exchange()
.expectStatus()
.isOk();
}
#Test
public void testPatchNoChanges() {
given(categoryRepository.findById(anyString()))
.willReturn(Mono.just(Category.builder().build()));
given(categoryRepository.save(any(Category.class)))
.willReturn(Mono.just(Category.builder().build()));
Mono<Category> catToUpdateMono = Mono.just(Category.builder().build());
webTestClient.patch()
.uri("/api/v1/categories/asdfasdf")
.body(catToUpdateMono, Category.class)
.exchange()
.expectStatus()
.isOk();
verify(categoryRepository, never()).save(any());
}
}
Any help would be greatly appreciated.
Your test is annotated with the JUnit4's #Test annotation but you are trying to run it with JUnit5. JUnit5 cannot see it.
Uncomment the org.junit.jupiter.api.Test import and remove import org.junit.Test (CategoryControllerTest).
Remove implementation 'junit:junit:4.12' from the build.gradle as well.

Why cannot import org.springframework.data cannot be resolved

I get an error in he "import org.springframework.data cannot be
resolved" in following code
package com.steinko.reactsprinboottutorial.RestfulWebService;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface TodoRepository extends CrudRepository<Todo, Long>{
List<Todo> findByName(String Name);
}
The gradle build.gradle looks like
plugins {
id 'org.springframework.boot' version '2.3.3.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}
apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
mavenCentral()
jcenter()
mavenLocal()
// maven { url "http://dl.bintray.com/epam/reportportal" }
}
sourceCompatibility = '14'
sourceSets {
intTest {
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
}
}
configurations {
intTestImplementation.extendsFrom implementation
intTestCompile.extendsFrom testCompile
intTestRuntimeOnly.extendsFrom runtimeOnly
}
dependencies {
//implementation 'com.epam.reportportal:logger-java-log4j:5.0.2'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.modelmapper:modelmapper:2.3.8'
// https://mvnrepository.com/artifact/javax.validation/validation-api
compile group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
implementation 'org.springframework.boot:spring-boot-starter-validation'
runtimeOnly 'org.postgresql:postgresql'
// https://mvnrepository.com/artifact/org.testcontainers/testcontainers
testCompile group: 'org.testcontainers', name: 'testcontainers', version: '1.15.0-rc1'
testCompile group: 'org.testcontainers', name: 'postgresql', version: '1.15.0-rc1'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:spring-mock-mvc:4.3.1'
testImplementation 'io.rest-assured:rest-assured-common:4.3.1'
testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa'
testCompile group: 'org.modelmapper', name: 'modelmapper', version: '2.3.8'
testImplementation 'com.epam.reportportal:agent-java-junit5:5.0.0-RC-1'
intTestCompile group: 'org.testcontainers', name: 'testcontainers', version: '1.15.0-rc1'
intTestCompile group: 'org.testcontainers', name: 'postgresql', version: '1.15.0-rc1'
intTestImplementation 'org.springframework.boot:spring-boot-starter-test'
intTestImplementation 'io.rest-assured:spring-mock-mvc:4.1.2'
intTestImplementation 'com.epam.reportportal:agent-java-junit5:5.0.0-RC-1'
intTestRuntimeOnly 'org.postgresql:postgresql'
}
test {
// testLogging.showStandardStreams = true
useJUnitPlatform()
// systemProperty 'junit.jupiter.extensions.autodetection.enabled', true
}
task integrationTest(type: Test) {
description = 'Runs integration tests.'
group = 'verification'
testClassesDirs = sourceSets.intTest.output.classesDirs
classpath = sourceSets.intTest.runtimeClasspath
shouldRunAfter test
}
When I run the test for the service I get a nullpointer for repository
TodoServiceTest > shoulCreateTodo() FAILED
java.lang.NullPointerException at TodoServiceTest.java:55
TodoServiceTest > shouldDeleteTodo() FAILED
java.lang.NullPointerException at TodoServiceTest.java:48
package com.steinko.reactsprinboottutorial.RestfulWebService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Disabled;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
public class TodoServiceTest {
private static final Logger logger = LoggerFactory.getLogger(TodoServiceTest.class);
private TodoService service = new TodoService();
#Test
void ShouldExist() {
assertNotNull (service);
}
#Test
void shouldDeleteTodo() {
service.deleteTodo("stein", 1L);
}
#Test
void shoulCreateTodo() {
Date date = DateFactory.generetDate("01-01-2020 12:00:00");
TodoDto todo = new TodoDto(1,"Stein","Fix Kjakk", date,false);
service.createTodo(todo);
}
}
The service test looks like
package com.steinko.reactsprinboottutorial.RestfulWebService;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Service
public class TodoService {
private static final Logger logger = LoggerFactory.getLogger(TodoService.class);
#Autowired
private TodoRepository repository;
public List<TodoDto> getTodos(String name) {
List<Todo> todos = repository.findByName(name);
TodoConverter converter = new TodoConverter();
List<TodoDto> dtos = converter.convertToDtos(todos);
return dtos;
}
public void deleteTodo(String name, Long id) {
repository.deleteById(id);
}
public void createTodo(TodoDto dto) {
TodoConverter converter = new TodoConverter();
Todo todo = converter.convertToEntity(dto);
validateEntity(todo);
repository.save(todo);
}
private void validateEntity(Todo todo) {
List<String> errorMessage = new ArrayList<>();
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Todo>> constraintViolations = validator.validate(todo);
for (ConstraintViolation<Todo> constraintViolation : constraintViolations) {
errorMessage.add(constraintViolation.getMessage());
}
if (errorMessage.size() > 0) {
throw new ConstraintViolationException(constraintViolations);
}
}
}
How do I get access to org.springframework.data and an object at repository variabel ?
You have to annotate the test class with either #SpringBootTest or #DataJpaTest so the repository will be initialised and injected into your service. Furthermore, you have to autowire your service in the test, or the repository will not be injected in the instance created by you.

Categories