Als ich mich zu sehr an JUnit4 gewöhnt hatte und mich entschied, in JUnit5 zu schreiben, musste ich einiges untersuchen. Jetzt werde ich die häufig verwendeten Implementierungsbeispiele für mich zusammenfassen.
Die zu testende Webanwendung setzt die Rest-API voraus und enthält den View-Layer-Test nicht.
Controller-Test Stellen Sie mit MockMVC eine Pseudoanforderung und testen Sie Filter + Controller + ExceptionHandler
Mit Mock testen
Verspotten Sie die Bohne und testen Sie sie
Machen Sie einen DI und den anderen Mock zum Testen
Parametrisierungstest Wiederholen Sie denselben Fall, wobei nur die Testdaten geändert wurden
Erstellen Sie zunächst eine zu testende App. Wie üblich Erstellt durch Hinzufügen von Lombok, Spring Web und Validation zu GradleProject mit Spring Initializr .RELEASE & package = jar & jvmVersion = 11 & groupId = com.example & artefaktId = demo & name = demo & description = Demo% 20project% 20for% 20Spring% 20Boot & packageName = com.example.demo & dependencies = lombok, web, validation).
build.gradle
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testCompileOnly 'org.projectlombok:lombok' //hinzufügen
testAnnotationProcessor 'org.projectlombok:lombok' //hinzufügen
}
test {
useJUnitPlatform()
}
Für das generierte "build.gradle" wurden zwei Zeilen zu "dependency" hinzugefügt, damit "lombok" im Testcode verwendet werden kann. (Siehe Kommentare oben) Wir werden die folgenden Klassen für dieses Projekt erstellen.
Erstellen Sie zwei "Services", die von "Controller" aufgerufen werden. Zunächst führt es eine einfache interne Verarbeitung durch.
DemoService.java
@Service
public class DemoService {
//Ich werde dich begrüßen
public String hello() {
return "hello";
}
//Ich werde teilen
public BigDecimal divide(BigDecimal a, BigDecimal b) {
return a.divide(b, 2, RoundingMode.HALF_UP);
}
}
Die andere besteht darin, eine externe Ressource (Qiita-API) zu erwerben.
ExternalService.java
@Service
@RequiredArgsConstructor
public class ExternalService {
private static final String EXTERNAL_RESOURCE_URL = "https://qiita.com/api/v2/schema";
private final RestTemplate restTemplate;
//Gibt das Ergebnis des Schemas der Qiita-API zurück
public String getExternalResource() {
ResponseEntity<String> response =
restTemplate.exchange(EXTERNAL_RESOURCE_URL, HttpMethod.GET, null, String.class);
return response.getBody();
}
}
Erstellen Sie eine "Configuration" -Klasse, um die oben genannte "restTemplate" zu erstellen.
AppConfig.java
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Erstellen Sie einen Controller, der die beiden zuvor genannten Dienste verwendet.
DemoController.java
@RestController
@RequiredArgsConstructor
@Validated
public class DemoController {
private final DemoService demoService;
private final ExternalService externalService;
//Ich werde dich begrüßen
@GetMapping("/")
public CommonResponse hello() {
String data = demoService.hello();
return CommonResponse.builder().data(data).build();
}
//Ich werde teilen
@GetMapping("/divide/{num1}/{num2}")
public CommonResponse divide(
@PathVariable @Pattern(regexp = "[0-9]*") String num1,
@PathVariable @Pattern(regexp = "[0-9]*") String num2) {
BigDecimal data = demoService.divide(new BigDecimal(num1), new BigDecimal(num2));
return CommonResponse.builder().data(data).build();
}
//Gibt das Ergebnis des Schemas der Qiita-API zurück
@GetMapping("/external")
public CommonResponse external() {
String data = externalService.getExternalResource();
return CommonResponse.builder().data(data).build();
}
}
Da die Abteilung die Eingabe überprüft, werden wir den Testfall später unter diesem Gesichtspunkt implementieren. Erstellen Sie die Antwortklasse wie folgt.
CommonResponse.java
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CommonResponse<T> {
@Builder.Default
private String status = "success";
@Builder.Default
private String message = "request succeeded.";
private T data;
}
Wir werden auch einen Filter und einen ExceptionHandler für ein praktischeres Beispiel erstellen. Dieser Filter ist so einfach wie die Ausgabe eines Protokolls vor und nach der Verarbeitung einer Anforderung.
LogFilter.java
@Component
@Slf4j
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
log.info("[IN]{}:{}", req.getMethod(), req.getRequestURI());
try {
chain.doFilter(request, response);
} finally {
log.info("[OUT]{}:{}", req.getMethod(), req.getRequestURI());
}
}
}
Erstellen Sie auch einen ExceptionHandler. Es wird verwendet, um verschiedene Fehler gemeinsam zu behandeln.
CommonExceptionHandler.java
@RestControllerAdvice
@Slf4j
public class CommonExceptionHandler extends ResponseEntityExceptionHandler {
// 404:Behandelt Fehler "Ressource nicht gefunden"
//* Um diese Anwendung zu behandeln.Sie müssen auch Eigenschaften festlegen
@Override
protected ResponseEntity handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
ServletWebRequest req = (ServletWebRequest)request;
log.warn("resource not found. {}", req.getRequest().getRequestURI());
return new ResponseEntity(
CommonResponse.builder().status("failure").message("resource not found.").build(),
HttpStatus.NOT_FOUND);
}
// 400:Behandelt Eingabeprüfungsfehler
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<CommonResponse> handleValidationError(ConstraintViolationException e) {
//Trennen Sie Eingabefehlerelemente und Meldungen durch Kommas(,)Hinzugefügt zu.
String validationErrorMessages =
e.getConstraintViolations().stream()
.map(cv -> cv.getPropertyPath().toString() + ":" + cv.getMessage())
.collect(Collectors.joining(", "));
log.info("Bad request. {}", validationErrorMessages);
return new ResponseEntity<>(
CommonResponse.builder().status("failure").message(validationErrorMessages).build(),
HttpStatus.BAD_REQUEST);
}
// 500:Ich werde andere unbekannte Fehler behandeln
@ExceptionHandler
public ResponseEntity<CommonResponse> handleException(Exception e) {
log.error("Request failed.", e);
return new ResponseEntity<>(
CommonResponse.builder().status("failure").message("error has occurred.").build(),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Fügen Sie die folgenden Einstellungen in application.properties
ein, um 404: Resouce Not Found
im obigen ExceptionHandler zu behandeln.
application.properties
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
Damit ist die Vorbereitung der zum Testen zu verwendenden Anwendung abgeschlossen. Die bis zu diesem Zeitpunkt bearbeiteten und erstellten Dateien haben die folgende Struktur.
├── build.gradle
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com.example.demo
│ │ │ ├── AppConfig.java
│ │ │ ├── DemoApplication.java
│ │ │ ├── controller
│ │ │ │ ├── CommonExceptionHandler.java
│ │ │ │ ├── CommonResponse.java
│ │ │ │ └── DemoController.java
│ │ │ ├── filter
│ │ │ │ └── LogFilter.java
│ │ │ └── service
│ │ │ ├── DemoService.java
│ │ │ └── ExternalService.java
│ │ └── resources
│ │ └── application.properties
│ └── test
└── web
Die Hauptrollen von Controller sind wie folgt.
Da diese Verhaltensweisen von der Funktionalität von Spring MVC abhängen, ist es wenig sinnvoll, Testcode nur für die Controller-Klasse zu schreiben. Daher werden wir "MockMVC" verwenden, um einen Test durchzuführen, der das Verhalten von Spring MVC reproduziert.
In Bezug auf die vom Controller akzeptierte Anforderung wird nicht nur der Normalfall, sondern auch die Antwort des angenommenen abnormalen Falls, wie z. B. ein Eingabeprüffehler, ausnahmslos überprüft.
DemoControllerTest.java
package com.example.demo.controller;
import com.example.demo.filter.LogFilter;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@EnableWebMvc
@Slf4j
public class DemoControllerTest {
MockMvc mockMvc;
@Autowired WebApplicationContext webApplicationContext;
@Autowired LogFilter logFilter;
@BeforeEach
void beforeEach() {
mockMvc =
MockMvcBuilders.webAppContextSetup(webApplicationContext) //Richten Sie Mock MVC ein
.addFilter(logFilter, "/*") //Der Filter muss jedoch manuell hinzugefügt werden
.build();
}
//Wurzel"/Ich werde Ihre Anfrage testen
@Test
void hello() throws Exception {
mockMvc.perform(get("/")) //Wurzel"/Senden Sie eine Pseudoanfrage an
.andExpect(status().isOk()) //HttpStatus ist 200:Okay sein
.andExpect(jsonPath("$.status").value("success")) //Der Wert von json ist wie erwartet
.andExpect(jsonPath("$.message").value("request succeeded.")) // 〃
.andExpect(jsonPath("$.data").value("hello"));
}
//Ich werde die Teilungsanfrage testen (10/3)
@Test
void divideSuccess() throws Exception {
mockMvc
.perform(get("/divide/10/3")) // 「/divide/10/Pseudoanfrage an 3 "senden
.andExpect(status().isOk()) //HttpStatus ist 200:Okay sein
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").value("3.33")); // 10 ÷ 3 = 3.Sei 33
}
//Test auf schlechte Anfragen (10 ÷ aaa)
@Test
void divideInvalidParameter() throws Exception {
mockMvc
.perform(get("/divide/10/aaa")) // 「/divide/10/Senden Sie eine Pseudoanfrage an "aaa"
.andExpect(status().isBadRequest()) //HttpStatus ist 400:Ein BadRequest sein
.andExpect(jsonPath("$.status").value("failure"))
.andExpect(jsonPath("$.message").value("divide.num2:must match \"[0-9]*\"")); //Es liegt eine Fehlermeldung vor
}
//Ich werde eine Anfrage für die Nullteilung testen (10 ÷ 0)
@Test
void divideZeroError() throws Exception {
mockMvc
.perform(get("/divide/10/0")) // 「/divide/10/Pseudoanforderung an "0" senden
.andExpect(status().is5xxServerError()) //HttpStatus ist 500:ServerError
.andExpect(jsonPath("$.status").value("failure"))
.andExpect(jsonPath("$.message").value("error has occurred."));
}
//Testen Sie die Erfassung externer Ressourcen (Qiita-Schema-API)
@Test
void getExternalResource() throws Exception {
MvcResult mvcResult =
mockMvc
.perform(get("/external"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").isNotEmpty()) //Nicht leer
.andReturn();
//Ich werde die erfasste Antwort auf das Protokoll ausgeben
log.info("external response : {}", mvcResult.getResponse().getContentAsString());
}
}
Der Punkt ist, MockMvc
mit WebAppicationContext
einzurichten. [^ 1]
Auf diese Weise können Sie den Status reproduzieren, der fast dem Bereitstellen auf dem Anwendungsserver entspricht.
[^ 1]: MockMvc verfügt auch über ein anderes eigenständiges Setup, und es gibt auch einen Modus, der für Unit-Tests geeignet ist und genau angepasst werden kann, z. B. Controller, ControllerAdvice, Config zum Testen.
** Beachten Sie jedoch, dass Sie nur Filter
mit addFilter (Filter," path ")
angeben müssen. ** ** **
Der vorherige Test verwendete DI Controller and Service.
Wenn Sie jedoch eine externe Ressource wie "ExternalService" verwenden, ist es nicht gut, dass der Controller-Test aufgrund des Status fehlschlägt (der andere Server ist ausgefallen und nicht erreichbar, Wi-Fi ist ausgeschaltet usw.). ..
** Verwenden Sie zu solchen Zeiten Mock. ** ** **
Wenn Sie die Rolle des Controllers erneut überprüfen,
Von diesen kann jedoch "4. Calling Business Logic (Service)" verspottet werden, um den erwarteten Wert zurückzugeben, sodass Sie sich auf das Testen des Controllers konzentrieren können.
Lassen Sie uns die Service-Klasse des vorherigen Tests in Mock konvertieren.
DemoControllerWithMockTest.java
package com.example.demo.controller;
import com.example.demo.filter.LogFilter;
import com.example.demo.service.DemoService;
import com.example.demo.service.ExternalService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import java.math.BigDecimal;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@EnableWebMvc
@Slf4j
class DemoControllerWithMockTest {
MockMvc mockMvc;
@Autowired WebApplicationContext webApplicationContext;
@Autowired LogFilter logFilter;
@MockBean DemoService demoService; //In Mock konvertieren und im DI-Container registrieren
@MockBean ExternalService externalService; // 〃
@BeforeEach
void beforeEach() {
MockitoAnnotations.initMocks(this);
mockMvc =
MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(logFilter, "/*")
.build();
}
@AfterEach
void afterEach() {}
@Test
void hello() throws Exception {
// mock
when(demoService.hello()).thenReturn("Hallo"); //Stellen Sie zuerst den Rückgabewert des Mocks ein
// request execute
mockMvc
.perform(get("/"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").value("Hallo")); //Überprüfen Sie dies, indem Sie den erwarteten Wert ändern
// verify
verify(demoService, times(1)).hello(); //Überprüfen Sie die Anzahl der Scheinanrufe
}
@Test
void divideSuccess() throws Exception {
// mock
when(demoService.divide(any(), any())).thenReturn(new BigDecimal("3.33")); //Unabhängig vom Argument"3.33"Gib es zurück
// request execute
mockMvc
.perform(get("/divide/10/3"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").value("3.33"));
// verify
verify(demoService, times(1)).divide(any(), any());
}
@Test
void divideInvalidParameter() throws Exception {
// request execute
mockMvc
.perform(get("/divide/10/aaa"))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.status").value("failure"))
.andExpect(jsonPath("$.message").value("divide.num2:must match \"[0-9]*\""));
// verify
verify(demoService, times(0)).divide(any(), any()); //Der Mock-Aufruf wurde aufgrund eines Eingabefehlers 0-mal validiert
}
@Test
void divideZeroError() throws Exception {
// mock
when(demoService.divide(any(), eq(BigDecimal.ZERO)))
.thenThrow(new ArithmeticException("/ by zero")); //Reproduzieren Sie den Fehler unter der Annahme einer Nullteilung
// request execute
mockMvc
.perform(get("/divide/10/0"))
.andExpect(status().is5xxServerError())
.andExpect(jsonPath("$.status").value("failure"))
.andExpect(jsonPath("$.message").value("error has occurred."));
// verify
verify(demoService, times(1)).divide(any(), eq(BigDecimal.ZERO)); //Scheinanruf wird einmal validiert
}
@Test
void getExternalResource() throws Exception {
// mock
when(externalService.getExternalResource())
.thenReturn("this is mock data for internal test."); //Geben Sie den Wortlaut zurück, ohne auf externe Ressourcen zuzugreifen
// request execute
MvcResult mvcResult =
mockMvc
.perform(get("/external"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").value("this is mock data for internal test."))
.andReturn();
//Ich werde die erfasste Antwort auf das Protokoll ausgeben
log.info("external response : {}", mvcResult.getResponse().getContentAsString());
// verify
verify(externalService, times(1)).getExternalResource(); //Scheinanruf wird einmal validiert
}
}
Am wichtigsten bei dieser Änderung ist, dass "ExternalService" jetzt Scheindaten zurückgibt, ohne auf externe Ressourcen zuzugreifen.
Sie können jetzt Controller-Tests unabhängig von externen Ressourcen ausführen.
Im vorherigen Test wurden sowohl "DemoService" als auch "ExternalService" verspottet, aber ** nur einer kann verspottet werden **. Wenn Sie beispielsweise nur "ExternalService" verspotten möchten, ist dies wie folgt.
DemoControllerWithOneSideMockTest.java
package com.example.demo.controller;
import com.example.demo.filter.LogFilter;
import com.example.demo.service.ExternalService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@EnableWebMvc
@Slf4j
class DemoControllerWithOneSideMockTest {
MockMvc mockMvc;
@Autowired WebApplicationContext webApplicationContext;
@Autowired LogFilter logFilter;
@MockBean ExternalService externalService; //Externer Dienst hat externen Zugriff, also machen Sie es verspotten
@BeforeEach
void beforeEach() {
MockitoAnnotations.initMocks(this);
mockMvc =
MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(logFilter, "/*")
.build();
}
@AfterEach
void afterEach() {}
@Test
void hello() throws Exception {
mockMvc
.perform(get("/"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").value("hello"));
}
@Test
void divideSuccess() throws Exception {
mockMvc
.perform(get("/divide/10/3"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").value("3.33"));
}
@Test
void divideInvalidParameter() throws Exception {
mockMvc
.perform(get("/divide/10/aaa"))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.status").value("failure"))
.andExpect(jsonPath("$.message").value("divide.num2:must match \"[0-9]*\""));
}
@Test
void divideZeroError() throws Exception {
mockMvc
.perform(get("/divide/10/0"))
.andExpect(status().is5xxServerError())
.andExpect(jsonPath("$.status").value("failure"))
.andExpect(jsonPath("$.message").value("error has occurred."));
}
//Nur der Erwerb externer Ressourcen wird mit Mock überprüft.
@Test
void getExternalResource() throws Exception {
// mock
when(externalService.getExternalResource()).thenReturn("this is mock data for internal test.");
// request
MvcResult mvcResult =
mockMvc
.perform(get("/external"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("success"))
.andExpect(jsonPath("$.message").value("request succeeded."))
.andExpect(jsonPath("$.data").value("this is mock data for internal test."))
.andReturn();
//
log.info("external response : {}", mvcResult.getResponse().getContentAsString());
// verify
verify(externalService, times(1)).getExternalResource();
}
}
Mit dieser Option können Sie die Bohne zum Zeitpunkt des Tests frei DI oder zu einem Mock machen. Sehr angenehm! !!
Schließlich werde ich ein Beispiel der in JUnit5 hinzugefügten Komfortfunktion "Parametrisierungstest" am Beispiel des Komponententests "Service" hinterlassen. Es ist einfach, denselben Fall zu wiederholen, indem nur die Testdaten geändert werden.
DemoServiceTest.java
package com.example.demo.service;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
class DemoServiceTest {
@Autowired DemoService demoService;
@Test
void hello() {
assertEquals("hello", demoService.hello());
}
// @Ich werde die Teilungsmethode mit verschiedenen Eingabemustern mit ParameterizedTest testen
@ParameterizedTest
@MethodSource("divideTestArgs") // "devideTestArgs"Ich werde eine statische Methode namens verwenden
void divide(String b1, String b2, String strExpect, boolean hasError) {
BigDecimal expect = Optional.ofNullable(strExpect).map(BigDecimal::new).orElse(null);
BigDecimal actual = null;
Exception error = null;
//Ausführung der Ausführungsmethode
try {
actual = demoService.divide(new BigDecimal(b1), new BigDecimal(b2));
} catch (Exception e) {
error = e;
}
//Erwarteter Wert und Überprüfung
assertEquals(expect, actual);
//Stellen Sie sicher, dass kein Fehler aufgetreten ist
assertEquals(hasError, error != null);
}
//Testparameterliste teilen
static List<Object[]> divideTestArgs() {
return List.of(
new Object[] {"1", "1", "1.00", false},
new Object[] {"0", "1", "0.00", false},
new Object[] {"5", "2", "2.50", false},
new Object[] {"10", "3", "3.33", false}, //Rundung (Abrundung der dritten Ziffer des Dezimalpunkts)
new Object[] {"11", "3", "3.67", false}, //Rundung (Aufrunden der dritten Stelle des Dezimalpunkts)
new Object[] {"1", "0", null, true}); //Teilen Sie auf Null
}
}
Außerdem MethodSource
Es scheint, dass Sie beispielsweise als Datenquelle verwenden können.
Informationen zur Funktion von JUnit5 [diese Seite](https://qiita.com/opengl-8080/items/efe54204e25f615e322f#%E3%83%91%E3%83%A9%E3%83%A1%E3%83% BC% E3% 82% BF% E5% 8C% 96% E3% 83% 86% E3% 82% B9% E3% 83% 88) war sehr einfach zu verstehen! Ich war sehr hilfreich mm
Es gibt viele Artikel zum Testen von JUnit, aber es gibt auch einige Artikel zu älteren Versionen. Ich hoffe, dass dies für Anfänger hilfreich ist, die sich mit Spring Boot und JUnit 5 herausfordern.
Recommended Posts