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

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));
}
}

Related

Field dao in com.car.services.CarServices required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found

Im trying to learn spring-boot basic application and unable to solve this error
APPLICATION FAILED TO START
Description:
Field dao in com.car.services.CarServices required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.
repository file
#SuppressWarnings("unused")
#Transactional
#Repository
public class CarDAO implements ICarDAO {
#PersistenceContext
private EntityManager entityManager;
#SuppressWarnings("unchecked")
#Override
public List<Car> getCars() {
//String hql = "FROM Car ";
String hql = "FROM Car as a ORDER BY a.id DESC";
return (List<Car>) entityManager.createQuery(hql).getResultList();
}
#Override
public Car getCar(int carId) {
return entityManager.find(Car.class, carId);
}
}
my 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.7.8</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.car</groupId>
<artifactId>car</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>car-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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.32</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
service file
#Service
public class CarServices implements ICarServices {
#Autowired
private ICarDAO dao;
#Override
public List<Car> getCars() {
return dao.getCars();
}
#Override
public Car getCars(int carId) {
return dao.getCar(carId);
}
}
Controller file
#RestController
#RequestMapping("carservice")
public class CarController {
#Autowired
private ICarServices service;
#GetMapping("car")
public ResponseEntity<List<Car>> getCars(){
List<Car> cars = service.getCars();
return new ResponseEntity<List<Car>>(cars, HttpStatus.OK);
}
}
main function
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class CarDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CarDemoApplication.class, args);
System.out.println("hello from car");
}
}
application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/cardb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.max-idle=20
spring.datasource.tomcat.min-idle=15
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.id.new_generator_mappings = false
spring.jpa.properties.hibernate.format_sql = true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
I tried
import org.springframework.beans.factory.annotation.Autowired;
in my repository.java file but it didnt work for me.
You need to remove DataSourceAutoConfiguration.class from exclusions. That is what sets up the EntityManagerFactory.
So this:
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
// Main class definition
Should be:
#SpringBootApplication()
// Main class definition

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)}

Unit testing for spring boot RESTFUL Controller

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.

Repository won't Beanify

I have an error that I can't track down. I'm new so sorry if I missed this in the searches, but I tried several things and no luck.
UserApi.java:
package com.jsp.jsp;
import com.jsp.models.User;
import com.jsp.services.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
class UserApi {
private final UserService userService;
public UserApi(UserService userService) {
this.userService = userService;
}
#RequestMapping(value="/api/user", method=RequestMethod.POST)
public User createUser(
#RequestParam(value="name", required=true) String name,
#RequestParam(value="email", required=true) String email,
#RequestParam(value="password", required=true) String password,
#RequestParam(value="confirm", required=true) String confirm)
{
User u = this.userService.createUser(new User(name, email, password));
return u;
}
}
UserRepository.java:
package com.jsp.repositories;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import com.jsp.models.User;
import org.springframework.data.repository.CrudRepository;
#Repository
public interface UserRepository extends CrudRepository<User, Long> {
List<User> findByEmail(String email);
Optional<User> findById(Long id);
List<User> findAll();
}
Server.java
package com.jsp.jsp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#SpringBootApplication(scanBasePackages={"com.jsp.models","com.jsp.repositories","com.jsp.services"})
#RestController
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}
UserService.java
package com.jsp.services;
import java.util.List;
import com.jsp.models.User;
import com.jsp.repositories.UserRepository;
import org.springframework.stereotype.Service;
#Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> allUsers() {
return this.userRepository.findAll();
}
public User createUser(User u) {
return this.userRepository.save(u);
}
}
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 http://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.1.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.jsp</groupId>
<artifactId>jsp</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-web</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>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.7.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
So in short, when I run the above project in VSCode, it errors out with the following:
2019-02-23 19:07:52.744 WARN 25412 --- [ restartedMain]
ConfigServletWebServerApplicationContext : Exception encountered
during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userService' defined in file
[C:\Users\Alex\Documents\dojo\javatown\everything\target\classes\com\jsp\services\UserService.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.jsp.repositories.UserRepository'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {}
My understanding is that the repository I made should be automatically turned into a bean and then wire itself up to the service I made. However, that seems to be not happening. My example videos are using MySQL -- will that make a difference? Am I using the right driver for Postgres 11? I'm super lost.
Some remarks and suggestions:
1.add autowired annotation on your constructor, it is clearer what you need spring to do.
#Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
2. I don't understand #RestController annotation on your main class.
#SpringBootApplication(scanBasePackages {"com.jsp.models","com.jsp.repositories","com.jsp.services"})
#RestController --> THIS CAN BE REMOVED
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}
3.You should add #EnableJpaRepositories("com.jsp.repositories") on your spring boot application => it will scan the repositories in that package.
#SpringBootApplication(scanBasePackages {"com.jsp.models","com.jsp.repositories","com.jsp.services"})
#EnableJpaRepositories("com.jsp.repositories")
public class Server {
public static void main(String[] args) {
SpringApplication.run(Server.class, args);
}
}

Categories

Resources