--Spring Boot + Spring Retry-Beispielprogramm, das automatisch mit Spring Test getestet wurde --Verwenden Sie zum Testen den Federtest + Mockito + JUnit 4
├── pom.xml
└── src
├── main
│ └── java
│ └── sample
│ ├── EchoController.java
│ ├── EchoRepository.java
│ └── EchoService.java
└── test
└── java
└── sample
└── EchoServiceTest.java
Führen Sie diesmal den Build mit Maven aus. pom.xml basiert auf der von Spring Initializr generierten. Fügen Sie den Abhängigkeiten Spring-Retry hinzu, um Spring Retry zu verwenden. Fügen Sie außerdem Spring-Boot-Starter-AOP hinzu, da die AOP-Klasse zur Laufzeit erforderlich ist. Fügen Sie den Spring-Boot-Starter-Test hinzu, um den Spring Test zu verwenden.
<?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.2.0.M4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>info.maigo.lab</groupId>
<artifactId>sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sample</name>
<description>Sample project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
EchoController.java
Es handelt sich um eine Starteintragsklasse von Spring Boot (mit Annotation @SpringBootApplication) sowie um eine Controller-Klasse (mit Annotation @RestController), die eine HTTP-Anforderung empfängt und eine Antwort zurückgibt. Die Annotation @EnableRetry wird angegeben, um Spring Retry zu aktivieren.
package sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
@EnableRetry
@RestController
public class EchoController {
public static void main(String[] args) {
SpringApplication.run(EchoController.class, args);
}
@Autowired
private EchoService service;
@RequestMapping("/{message}")
public Map<String, Object> index(@PathVariable("message") String message) {
return new HashMap<String, Object>() {
{
put("result", service.echo(message));
}
};
}
}
EchoRepository.java
Repository-Klasse.
package sample;
import org.springframework.stereotype.Repository;
import java.util.Random;
@Repository
public class EchoRepository {
public String echo(String message) {
//Es besteht eine halbe Chance, dass eine Ausnahme auftritt
if (new Random().nextBoolean()) {
return message;
} else {
throw new RuntimeException("Failure");
}
}
}
EchoService.java
Serviceklasse. Wenn eine RuntimeException in einer Methode auftritt, die die Spring Retry-Annotation @Retryable angibt, wird dieselbe Methode bis zu dreimal versucht.
package sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
@Service
public class EchoService {
@Autowired
private EchoRepository repository;
/**
*Gibt die angegebene Nachricht zurück.
*Gelegentlich schlägt es fehl, aber ich versuche es bis zu 3 Mal.
* @param message message
* @Rückmeldung
*/
@Retryable(
value = {RuntimeException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String echo(String message) {
System.out.println("EchoService#echo: " + message);
return repository.echo(message);
}
@Recover
public String recover(RuntimeException e, String message) {
System.out.println("EchoService#recover: " + message);
throw e;
}
}
EchoServiceTest.java
Testklasse für die EchoService-Klasse. Erstellen Sie ein Scheinobjekt von EchoRepository und testen Sie das Verhalten von EchoService.
package sample;
import org.junit.Test;
import org.junit.runner.RunWith;
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.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
@RunWith(SpringRunner.class) //Verwenden Sie JUnit für den Frühling
@SpringBootTest //Starten Sie Spring Boot und testen Sie
public class EchoServiceTest {
@Autowired
private EchoService service;
//Fügen Sie dem ApplicationContext einen Mock hinzu
// (Ersetzen Sie vorhandene Objekte, falls vorhanden)
@MockBean
private EchoRepository mockRepository;
@Test
public void testSuccess() {
//Bereiten Sie ein Modell von EchoRepository vor
//Dieser Mock gibt normalerweise einen Wert zurück
String message = "Zero";
doReturn(message).when(mockRepository).echo(message);
//Prüfung
assertEquals(message, service.echo(message));
}
@Test
public void testFairureSuccess() {
//Bereiten Sie ein Modell von EchoRepository vor
//Dieser Mock löst einmal eine Ausnahme aus und gibt dann den Wert normal zurück
String message = "Uno";
doThrow(new RuntimeException("Failure"))
.doReturn(message)
.when(mockRepository).echo(message);
//Prüfung
assertEquals(message, service.echo(message));
}
@Test
public void testFairureFairureSuccess() {
//Bereiten Sie ein Modell von EchoRepository vor
//Dieser Mock löst zweimal eine Ausnahme aus und gibt dann normal einen Wert zurück
String message = "Due";
doThrow(new RuntimeException("Failure"))
.doThrow(new RuntimeException("Failure"))
.doReturn(message)
.when(mockRepository).echo(message);
//Prüfung
assertEquals(message, service.echo(message));
}
@Test(expected = RuntimeException.class) //Annahme einer RuntimeException
public void testFairureFairureFairure() {
//Bereiten Sie ein Modell von EchoRepository vor
//Dieser Mock löst dreimal eine Ausnahme aus
String message = "Tre";
doThrow(new RuntimeException("Failure"))
.doThrow(new RuntimeException("Failure"))
.doThrow(new RuntimeException("Failure"))
.when(mockRepository).echo(message);
//Prüfung
service.echo(message);
}
}
Geben Sie den Befehl mvn test ein, um Spring Boot zu starten und den Test auszuführen.
$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< info.maigo.lab:sample >------------------------
[INFO] Building sample 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
(Unterlassung)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.0.M4)
(Unterlassung)
2019-07-20 20:12:34.687 INFO 25426 --- [ main] sample.EchoServiceTest : Started EchoServiceTest in 3.407 seconds (JVM running for 4.983)
EchoService#echo: Due
EchoService#echo: Due
EchoService#echo: Due
EchoService#echo: Tre
EchoService#echo: Tre
EchoService#echo: Tre
EchoService#recover: Tre
EchoService#echo: Uno
EchoService#echo: Uno
EchoService#echo: Zero
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.643 s - in sample.EchoServiceTest
2019-07-20 20:12:39.930 INFO 25426 --- [ Thread-1] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.650 s
[INFO] Finished at: 2019-07-20T20:12:40+09:00
[INFO] ------------------------------------------------------------------------
Recommended Posts