Unit testing for spring boot RESTFUL Controller - java

I am trying to do unit testing for spring boot RESTFUL controller but I am receiving a null pointer exception. The application has a StudentController which depends on a StudentService.
Here is the controller code:
package com.demo.student.demo.controller;
import com.demo.student.demo.annotation.ApiDescription;
import com.demo.student.demo.entity.Student;
import com.demo.student.demo.entity.StudentDto;
import com.demo.student.demo.service.StudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
#RestController
#RequestMapping(value = "/v1/students")
#Api(description = "This is a general description for StudentController RESTFUL Controller")
public class StudentController {
private StudentService studentService;
private ModelMapper modelMapper;
public StudentController(ModelMapper modelMapper, StudentService studentService){
this.studentService = studentService;
this.modelMapper = modelMapper;
}
private StudentDto convertToDto(Student student) {
StudentDto studentDto = modelMapper.map(student, StudentDto.class);
return studentDto;
}
private Student convertToEntity(StudentDto studentDto) {
Student student = modelMapper.map(studentDto, Student.class);
return student;
}
#GetMapping
#ApiOperation("Returns a list of all students in the system.")
#ApiDescription("FIND_ALL_STUDENTS.md")
public List<StudentDto> findAll(){
List<Student> students = studentService.findAl();
return students.stream()
.map(student -> convertToDto(student))
.collect(Collectors.toList());
}
#GetMapping("/{id}")
#ApiOperation("Returns a specific Student by his/her identifier. 404 if does not exist.")
#ApiDescription("FIND_STUDENT_BY_ID.md")
public StudentDto findById(#PathVariable("id") long id){
return convertToDto(studentService.findById(id));
}
#PostMapping
#ApiOperation("Creates/Updates a new Student.")
#ApiDescription("SAVE_OR_UPDATE_STUDENT.md")
public StudentDto saveOrUpdate(#RequestBody StudentDto studentDto) {
Student student = convertToEntity(studentDto);
student.setUsername(student.getEmail() + "----" + student.getId());
Student studentCreated = studentService.saveOrUpdate(student);
return convertToDto(studentCreated);
}
#DeleteMapping("/{id}")
#ApiOperation("Deletes a Student from the system. 404 if the Student's identifier is not found.")
#ApiDescription("DELETE_STUDENT_BY_ID.md")
public void deleteById(#PathVariable("id") long id){
studentService.deleteById(id);
}
}
And here is the service implementation code:
package com.demo.student.demo.service;
import com.demo.student.demo.entity.Student;
import com.demo.student.demo.exception.StudentNotFoundException;
import com.demo.student.demo.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class StudentServiceImpl implements StudentService {
private StudentRepository studentRepository;
#Autowired
public StudentServiceImpl(StudentRepository studentRepository){
this.studentRepository = studentRepository;
}
#Override
public List<Student> findAl() {
return studentRepository.findAll();
}
#Override
public Student findById(long id) {
return studentRepository.findById(id).orElseThrow(() -> new StudentNotFoundException(id));
}
#Override
public Student saveOrUpdate(Student student) {
studentRepository.save(student);
return student;
}
#Override
public void deleteById(long id) {
if(this.findById(id) != null)
studentRepository.deleteById(id);
}
}
And this is the test class for the controller:
package com.demo.student.demo.controller;
import com.demo.student.demo.entity.Student;
import com.demo.student.demo.service.StudentService;
import com.demo.student.demo.service.StudentServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Arrays;
import java.util.List;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
#WebMvcTest(StudentController.class)
class StudentControllerTest {
private final static String URI = "/v1/students";
#Autowired
private MockMvc mockMvc;
#MockBean
private StudentService studentService;
#Test
void findAll() throws Exception {
// given
Student student = new Student(1, "test", "test#test.test");
List<Student> students = Arrays.asList(student);
given(studentService.findAl()).willReturn(students);
// when + then
mockMvc.perform(get(URI))
.andExpect(status().isOk())
.andExpect(content().json("[{'id':1,'email':'test#test.test'}]"));
}
}
Here is also the pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.student</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>0.7.5</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
When I run the test I receive a NULL POINTER EXCEPTION pointing to a code line in the StudentController class where the student service retrieves all the student data: List<Student> students = studentService.findAl();
java.lang.NullPointerException: null
at com.demo.student.demo.controller.StudentController.findAll
Can anyone tell me what is the problem?

Finally I found an answer, to add #ExtendWith(SpringExtension.class) in order to work in JUnit5.
So, my controller test class would be:
package com.demo.student.demo.controller;
import com.demo.student.demo.entity.Student;
import com.demo.student.demo.service.StudentService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Arrays;
import java.util.List;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
#ExtendWith(SpringExtension.class)
#WebMvcTest
class StudentControllerTest {
private final static String URI = "/v1/students";
#Autowired
private MockMvc mockMvc;
#MockBean
private StudentService studentService;
#Test
void findAll() throws Exception {
// given
Student student = new Student(1, "test", "test#test.test");
List<Student> students = Arrays.asList(student);
given(studentService.findAl()).willReturn(students);
// when + then
mockMvc.perform(get(URI))
.andExpect(status().isOk())
.andExpect(content().json("[{'id':1,'email':'test#test.test'}]"));
}
}
And also here is the pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.student</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>0.7.5</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

There are a couple of things with your test, first you are mixing JUnit4 and JUnit5, don't, second you are trying to work against the Spring Boot created mock, don't. Finally you are creating a new mock for the service and register behavior.
Remove the #RunWith annotation, that is for JUnit4 tests and not needed with JUnit5.
Remove your #BeforeEach method, as that interferes with the prepared MockMvc by Spring Boot (through the #WebMvcTest) and the mock created by #MockBean.
Remove StudentService studentService = mock(StudentService.class); from your test method. #MockBean already creates a mock. This creates a new mock, not tied to the controller.
The version of Spring Boot used (2.0.x) doesn't yet have an #WebMvcTest that includes the #ExtendWith annotation (as of Spring Boot 2.1.x). So add that as well to use the proper execution model.
pro-tip: Remove the no-args constructor and #Autowired from your StudentController, Spring is smart enough to pick the single constructor.

Annotate your test class this way.
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Autowire this:
#Autowired
private WebApplicationContext wac;
This is just a class variable:
private MockMvc mockMvc;
Your setup method:
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
Before this line:
given(studentService.findAl()).willReturn(students);
Create:
StudentService studentService = org.mockito.Mockito.mock(StudentService.class);
It should run.

Related

Mockito testing void method which throws exception. Spring Boot, eclipse IDE

How to test a void method which throws an exception?
I've read many publications here and on others pages including Mockico docs form https://javadoc.io/static/org.mockito/mockito-core/3.12.4/org/mockito/Mockito.html#5. And my test still won't pass. I don't know what I'm doing wrong I always get red.
Maybe it is related to a wrongly implemented exception class.
Here is my code:
Repo:
import org.springframework.data.jpa.repository.JpaRepository;
import succeed.app.start.model.User;
public interface UserRepository extends JpaRepository<User, Long> {
}
Service interface:
public interface UserService {
void deleteUserById(long userId);
}
Service implementation:
#Service
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
#Override
public void deleteUserById(long userId) {
userRepository.findById(userId).orElseThrow(() -> new ResourceNotFoundException("User", "ID", userId));
userRepository.deleteById(userId);
}
}
Exception class:
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
#ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
private final static long serialVersionUID = 1L;
private String resourceName;
private String fieldName;
private Object fieldValue;
public ResourceNotFoundException(String resourceName, String fieldName, Object fieldValue) {
super(String.format("%s not found with %s : %s", resourceName, fieldName, fieldValue));
this.resourceName = resourceName;
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
public String getResourceName() {
return resourceName;
}
public String getFieldName() {
return fieldName;
}
public Object getFieldValue() {
return fieldValue;
}
}
Test class:
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.doThrow;
import succeed.app.start.exception.ResourceNotFoundException;
import succeed.app.start.repository.UserRepository;
#ExtendWith(MockitoExtension.class)
public class UserServiceImplTest {
#Mock
UserRepository userRepository;
#Mock
UserServiceImpl userService;
#Test
#DisplayName("Should throw ResourceNotFoundException when user doesn't exist.")
void shouldThrowsResourceNotFoundException() {
final long nonExistingId = 12902450235L;
doThrow(new ResourceNotFoundException("User", "ID", nonExistingId)).when(userService).deleteUserById(nonExistingId);
userService.deleteUserById(nonExistingId);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>succeed.app</groupId>
<artifactId>start</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>start</name>
<description>App to organize and achieve goals.</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</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>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
There are a couple of things wrong here.
First, other than the message in the #Display annotation, your test doesn't really expect the exception to be thrown. You need to explicitly code this behavior, e.g. by using assertThrows.
Second, you're mocking the UserService, so the test won't really do anything - in the same method, you've defined some fake behavior and then tested it. Instead, you should mock the UserRepository and then make test that the UserService calls it correctly:
#ExtendWith(MockitoExtension.class)
public class UserServiceImplTest {
#Mock
UserRepository userRepository;
#InjectMocks
UserServiceImpl userService;
#Test
#DisplayName("Should throw ResourceNotFoundException when user doesn't exist.")
void shouldThrowsResourceNotFoundException() {
final long nonExistingId = 12902450235L;
doReturn(Optional.empty()).when(userRepository).findById(nonExistingId);
assertThrows(
ResourceNotFoundException.class,
() -> userService.deleteUserById(nonExistingId));
}
}

postman returning "status": 404, "error": "Not Found", for the spring boot

Thank you in advance, Hello I am new to spring boot. I am facing a problem with spring boot. When I run my URL in postman it shows an error below. I have also uploaded my code below. I don't find any idea what wrong with my code.
{
"timestamp": "2021-07-09T06:43:57.429+00:00",
"status": 404,
"error": "Not Found",
"path": "/todo"
}
Controller code
This is a code for my controller code.
package com.assignment.todo.Todo.Controller;
import com.assignment.todo.Todo.Repo.*;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.assignment.todo.Todo.Model.*;
import com.assignment.todo.Todo.Repo.*;
#RestController
#RequestMapping(value="/todo")
public class TodoController {
#Autowired
private TodoRepo todoRepo;
#GetMapping
public List<TodoModel> findAll(){
return todoRepo.findAll();
}
#PostMapping
public TodoModel save(#Valid #NotNull #RequestBody TodoModel todoItem) {
return todoRepo.save(todoItem);
}
}
Model
code for my model class
package com.assignment.todo.Todo.Model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.validation.constraints.NotBlank;
import org.springframework.data.annotation.Id;
#Entity
public class TodoModel {
private Long id;
#NotBlank
private String title;
private boolean done;
public TodoModel() {
}
public TodoModel(long id, String title, boolean done) {
this.id=id;
this.title=title;
this.done=done;
}
#Id
#GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
}
Repo
code for my repo class
package com.assignment.todo.Todo.Repo;
import com.assignment.todo.Todo.Model.*;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TodoRepo extends JpaRepository<TodoModel, Long> {
}
MainClass
package com.assignment.todo.Todo;
import com.assignment.todo.Todo.Controller.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.assignment.todo.Todo.Repo.*;
#SpringBootApplication(scanBasePackages = "TodoRepo.java")
public class TodoApplication {
public static void main(String[] args) {
SpringApplication.run(TodoApplication.class, args);
}
}
pom.xml
My pom.xml file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.assignment.todo</groupId>
<artifactId>Todo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Todo</name>
<description>Assignment in Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepositosry.com/artifact/org.springframework/spring-web -->
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.istack/maven-istack-commons-plugin -->
<!-- https://mvnrepository.com/artifact/com.sun.istack/maven-istack-commons-plugin -->
<dependency>
<groupId>com.sun.istack</groupId>
<artifactId>maven-istack-commons-plugin</artifactId>
<version>2.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
#RestController("/todo")// you can give any URL here
public class TodoController {
#Autowired
private TodoRepo todoRepo;
#GetMapping("/getAll")// you can give any URL here
public List<TodoModel> findAll(){
return todoRepo.findAll();
}
#PostMapping("/save")// you can give any URL here
public TodoModel save(#Valid #NotNull #RequestBody TodoModel todoItem) {
todoRepo.save(todoItem);
return todoItem;
}
}
you give the mapping to the method like this. you can give any URL name. This is the main reason you get a 404 error.
There is issue in your mapping. You didn't specify the mapping path so findAll and save has default mapping as empty then controller could not understand which API you calling. Add below things and try.
#GetMapping(value="/findAll")
#PostMapping(value=/save")
The TodoApplication class must be above this one level.
change this:
from
package com.assignment.todo.Todo;
to
package com.assignment.todo;

how can i fix "Error 401 Unauthorized" on Spring Boot

I started watching a Tutorial on how to make a very basic Spring Boot Project. https://www.youtube.com/watch?v=vtPkZShrvXQ
No matter what i do i always get error 401, even when i copy the code 1-1.
Thank you in advance for taking your time to help me.
I tried putting this into the application.properties
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/LoginDB
spring.datasource.username=root
spring.datasource.password=
I made following Files
Folder structure
Player
package com.Project_A.Databaseconnection.Artifact.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.UUID;
public class Player {
private final UUID id;
private final String PlayerName;
public Player(#JsonProperty("id") UUID id,
#JsonProperty("playerName") String playerName
) {
this.id = id;
PlayerName = playerName;
}
public UUID getId() {
return id;
}
public String getPlayerName() {
return PlayerName;
}
}
PlayerDao
package com.Project_A.Databaseconnection.Artifact.dao;
import com.Project_A.Databaseconnection.Artifact.model.Player;
import java.util.List;
import java.util.UUID;
public interface PlayerDao {
int insertPlayer(UUID id, Player player);
default int insertPlayer(Player player){
UUID id = UUID.randomUUID();
return insertPlayer(id, player);
}
List<Player> selectAllPlayer();
}
FakePlayerDataAccessService
package com.Project_A.Databaseconnection.Artifact.dao;
import com.Project_A.Databaseconnection.Artifact.model.Player;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
#Repository("fakeDao")
public class FakePlayerDataAccessService implements PlayerDao {
private static List<Player> DB = new ArrayList<>();
#Override
public int insertPlayer(UUID id, Player player){
DB.add(
new Player(id,
player.getPlayerName()
//player.getPlayerPassword()
)
);
return 0;
}
#Override
public List<Player> selectAllPlayer() {
return DB;
}
}
PlayerController
package com.Project_A.Databaseconnection.Artifact.api;
import com.Project_A.Databaseconnection.Artifact.model.Player;
import com.Project_A.Databaseconnection.Artifact.service.PlayerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RequestMapping("api/v1/player")
#RestController
public class PlayerController {
private final PlayerService playerService;
#Autowired
public PlayerController(PlayerService playerService){
this.playerService = playerService;
}
#PostMapping
public void addPlayer(#RequestBody Player player) { playerService.addPlayer(player); }
#GetMapping
public List<Player> getAllPlayer() { return playerService.getAllPlayer(); }
}
pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.Project_A.Databaseconnection</groupId>
<artifactId>Artifact</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>LoginServerConnector</name>
<description>connection with the LoginServer</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
If you don't need spring security in your project then remove below 2 dependencies from your pom.xml file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
And if you need basic security then only use 2nd dependency And default user name is "user" and password you will get from console log.

Can not inject Repository in Spring Boot integrated with JavaFX

I have project with integrated JavaFX and Spring Boot as one. I have problem with an injecting repository to Controller of JavaFX.
I have annotation #Controller in JavaFX controller, but although it's every time reproduce the same error: No qualifying bean of type 'TaxRepository' available.
Has anyone idea how resolve this problem ? I want use TaxRepository in NewTaxWindowController, but when I has previous configuration with other spring integration I get every time null for TaxRepository.
Below is my configuration:
Maven pom file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hubertstruminski.invoice.app</groupId>
<artifactId>com-hubertstruminski-invoice-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>invoiceApp</name>
<description>Management system for invoices</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>de.jensd</groupId>
<artifactId>fontawesomefx</artifactId>
<version>8.9</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>io.github.fvarrui</groupId>
<artifactId>javapackager</artifactId>
<version>0.9.7</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>package</goal>
</goals>
<configuration>
<!-- mandatory -->
<mainClass>com.hubertstruminski.invoice.app.InvoiceAppApplication</mainClass>
<!-- optional -->
<bundleJre>true</bundleJre>
<generateInstaller>true</generateInstaller>
<administratorRequired>false</administratorRequired>
<platform>windows</platform>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
application.properties
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:file:./db/invoiceAppDatabase;MV_STORE=FALSE;MVCC=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=user
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
InvoiceAppApplication class - main Spring boot class which extends from Application Javafx class
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.jpa.repository.config.*;
#SpringBootApplication
#EntityScan(basePackages = {"com.hubertstruminski.invoice.app.model"})
public class InvoiceAppApplication extends Application {
private ConfigurableApplicationContext springContext;
private Parent rootNode;
public static void main(String[] args) {
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
Application.launch(args);
}
#Override
public void init() throws Exception {
springContext = SpringApplication.run(InvoiceAppApplication.class);
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/static/mainWindow.fxml"));
fxmlLoader.setControllerFactory(springContext::getBean);
rootNode = fxmlLoader.load();
}
#Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(rootNode));
stage.show();
}
#Override
public void stop() throws Exception {
springContext.close();
}
}
TaxRepository class
import com.hubertstruminski.invoice.app.model.Tax;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface TaxRepository extends CrudRepository<Tax, Long> {
public List<Tax> findByName(String name);
public List<Tax> findById(long id);
}
Tax model class
import javax.persistence.*;
#Entity
#Table(name = "Taxs")
public class Tax {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
private String description;
private String taxAmount;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTaxAmount() {
return taxAmount;
}
public void setTaxAmount(String taxAmount) {
this.taxAmount = taxAmount;
}
}
NewTaxWindowController JavaFX class
#Controller
public class NewTaxWindowController extends BaseController implements Initializable
{
#Autowired
private TaxRepository taxRepository;
#FXML
private Label nameLabel;
public NewTaxWindowController() {
}
public NewTaxWindowController(ViewCreator viewCreator, String fxmlName) {
super(viewCreator, fxmlName);
}
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
}
}
Stacktrace:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.xxxx.xxxx.xxxxx.repository.TaxRepository'
available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}

#DataJpaTest Junit 5 #Autowired NullPointer (SpringBoot)

I have created a new Spring Boot application using Spring Data.
I got an issue when I try to test my JpaRepository:
[ERROR] Failures:
[ERROR] EmployeeRepositoryTest.testDeleteEmployee:46 NullPointer
[ERROR] EmployeeRepositoryTest.testGetEmployee:37 NullPointer
[ERROR] EmployeeRepositoryTest.testSaveEmployee ยป Test
Expected exception of type cla...
java.lang.NullPointerException in the line
repository.save(employee);
where a repository has been defined as:
#Autowired
private EmployeeRepository repository;
Follow my pom.xml and test class:
#ExtendWith({SpringExtension.class})
#DataJpaTest
class EmployeeRepositoryTest {
#Autowired
private EmployeeRepository repository;
#Test(expectedExceptions = ResourceNotFoundException.class)
void testSaveEmployee() throws ResourceNotFoundException {
Employee employee = new Employee("John", "Smith", "john.smith#email.com");
repository.save(employee);
employee = repository.findById(employee.getId()).orElseThrow(() -> new ResourceNotFoundException(""));
assertNotNull(employee);
assertEquals(employee.getFirstName(), "John", "The employee firstname should be John");
}
}
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
</dependencies>
...
Could you please help to understand which is the issue?
Below the EmployeeRepository interface:
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>{
}

Categories

Resources