如何测试抛出异常的 void
方法?
我在这里和其他页面上阅读了许多出版物,包括 Mockico 文档表格 https://javadoc.io/static/org.mockito/mockito-core/3.12.4/org/mockito/Mockito.html#5 .而我的测试仍然不会通过。我不知道自己做错了什么,我总是脸红。
可能与错误实现的异常类有关。
这是我的代码:
repo :
import org.springframework.data.jpa.repository.JpaRepository;
import succeed.app.start.model.User;
public interface UserRepository extends JpaRepository<User, Long> {
}
服务接口(interface):
public interface UserService {
void deleteUserById(long userId);
}
服务实现:
@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);
}
}
异常类:
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;
}
}
测试类:
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>
最佳答案
这里有一些错误。
首先,除了 @Display
注释中的消息外,您的测试并不真正期望抛出异常。您需要明确编码此行为,例如通过使用 assertThrows
.
其次,您正在模拟 UserService
,因此测试不会真正执行任何操作 - 在相同的方法中,您已经定义了一些假行为,然后对其进行了测试。相反,您应该模拟 UserRepository
,然后测试 UserService
是否正确调用它:
@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));
}
}
关于java - Mockito 测试抛出异常的 void 方法。 Spring Boot,eclipse IDE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68965256/