├── pom.xml
└── src
├── main
│ └── java
│ └── sample
│ ├── EchoController.java
│ ├── EchoRepository.java
│ └── EchoService.java
└── test
└── java
└── sample
└── EchoServiceTest.java
Cette fois, exécutez la compilation avec Maven. pom.xml est basé sur celui généré par Spring Initializr. Ajoutez spring-retry aux dépendances pour utiliser Spring Retry. Ajoutez également spring-boot-starter-aop car la classe AOP est requise lors de l'exécution. Ajoutez spring-boot-starter-test pour utiliser Spring Test.
<?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
Il s'agit d'une classe d'entrée de démarrage de Spring Boot (avec l'annotation @SpringBootApplication), ainsi que d'une classe Controller (avec l'annotation @RestController) qui reçoit une requête HTTP et renvoie une réponse. L'annotation @EnableRetry est spécifiée pour activer Spring Retry.
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
Classe de référentiel.
package sample;
import org.springframework.stereotype.Repository;
import java.util.Random;
@Repository
public class EchoRepository {
public String echo(String message) {
//Il y a une demi-chance qu'une exception se produise
if (new Random().nextBoolean()) {
return message;
} else {
throw new RuntimeException("Failure");
}
}
}
EchoService.java
Classe de service. Lorsqu'une RuntimeException se produit dans une méthode qui spécifie l'annotation Spring Retry @Retryable, la même méthode est essayée jusqu'à 3 fois.
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;
/**
*Renvoie le message spécifié.
*Parfois, cela échoue, mais j'essaye jusqu'à 3 fois.
* @message de paramétrage
* @message de retour
*/
@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
Classe de test pour la classe EchoService. Créez un objet fictif d'EchoRepository et testez le comportement d'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) //Utilisez JUnit pour le printemps
@SpringBootTest //Lancez Spring Boot et testez
public class EchoServiceTest {
@Autowired
private EchoService service;
//Ajouter une maquette à ApplicationContext
// (Remplacez les objets existants, le cas échéant)
@MockBean
private EchoRepository mockRepository;
@Test
public void testSuccess() {
//Préparez une maquette d'EchoRepository
//Cette simulation renvoie une valeur normalement
String message = "Zero";
doReturn(message).when(mockRepository).echo(message);
//tester
assertEquals(message, service.echo(message));
}
@Test
public void testFairureSuccess() {
//Préparez une maquette d'EchoRepository
//Cette simulation lève une exception une fois, puis renvoie la valeur normalement
String message = "Uno";
doThrow(new RuntimeException("Failure"))
.doReturn(message)
.when(mockRepository).echo(message);
//tester
assertEquals(message, service.echo(message));
}
@Test
public void testFairureFairureSuccess() {
//Préparez une maquette d'EchoRepository
//Ce simulacre lève une exception deux fois, puis renvoie une valeur normalement
String message = "Due";
doThrow(new RuntimeException("Failure"))
.doThrow(new RuntimeException("Failure"))
.doReturn(message)
.when(mockRepository).echo(message);
//tester
assertEquals(message, service.echo(message));
}
@Test(expected = RuntimeException.class) //En supposant une exception RuntimeException
public void testFairureFairureFairure() {
//Préparez une maquette d'EchoRepository
//Cette simulation lève une exception 3 fois
String message = "Tre";
doThrow(new RuntimeException("Failure"))
.doThrow(new RuntimeException("Failure"))
.doThrow(new RuntimeException("Failure"))
.when(mockRepository).echo(message);
//tester
service.echo(message);
}
}
Entrez la commande mvn test pour lancer Spring Boot et exécuter le test.
$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< info.maigo.lab:sample >------------------------
[INFO] Building sample 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
(Omission)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.0.M4)
(Omission)
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