[JAVA] Führen Sie einen Transaktionsbestätigungstest mit Spring Boot durch

Einführung

Das Team, dem ich angehöre, hat die Regel, dass ich bei Problemen einen Testcode schreibe, ihn reproduziere (überprüfen Sie den roten Balken) und ihn dann behebe. Neulich gab es ein Problem, dass die Transaktionskontrolle fehlte, also habe ich versucht, einen Testcode zu schreiben, aber da ich verwirrt war, werde ich ihn organisieren und veröffentlichen. Der Testcode ist auf Github (https://github.com/shimi58/transactiontest) aufgeführt. Bitte beziehen Sie sich darauf.

Entwicklungsumgebung

Die auf Eclipse basierende Umgebung ist wie folgt. Ich habe ein Gradle-Projekt erstellt und es durch den Pfad geleitet.

Umgebung Ausführung
Java 1.8
SpringBoot 2.2.6
MyBatis 2.1.0
H2 PostgresqlMode
Junit 5(Jupiter)

Implementierungscode (Serviceklasse)

Registrieren Sie Mitarbeiterinformationen (Name, Telefonnummer, E-Mail-Adresse) und aktualisieren Sie die Nummer in der Mitarbeitertabelle auf die Statustabelle. Es ist eine Beispielquelle wie.


/**
 * Mitarbeiterservice
 */
@Service
public class EmployeeService {

    @Autowired
    EmployeeRepository employeeRepository;

    /**
 * Mitarbeiterregistrierung
     */
 @Transactional // ← Dies war undicht
    public EmployeeNumber register(Employee employee) {

        employeeRepository.registerEmployee(employee);
        Employees employees = employeeRepository.findEmployees();

        EmployeeNumber employeeNumber = employees.number();
        employeeRepository.registerNumber(employeeNumber);

        return employeeNumber;

    }

}

In dieser Beispielquelle wird sie als Mitarbeitertabelle → Statustabelle aktualisiert. Wenn die Transaktion jedoch nicht wirksam ist und die Aktualisierung der Statustabelle fehlschlägt, wird sie in der in der Mitarbeitertabelle enthaltenen Nummer- und Statustabelle beibehalten. Die Anzahl der Fälle ist inkonsistent.

Die Controller-Klasse wird übrigens später erwähnt, wenn der Testcode erklärt wird.

/**
 * Mitarbeiter-Controller
 */
@RestController
@RequestMapping("/employees")
public class EmployeesController {

    @Autowired
    EmployeeService employeeService;

    /**
 * Mitarbeiterregistrierung
     */
    @RequestMapping(value = "/register", method = {RequestMethod.POST})
    public String regist(@RequestBody Employee employee) {

        EmployeeNumber employeeNumber = new EmployeeNumber(0);

        try {
            employeeNumber = employeeService.register(employee);
        } catch (Exception e) {

 System.out.println ("Verarbeitungsfehler");
        }
        return employeeNumber.toString();


    }
}

Wie zu testen

Verwenden Sie ** @SpyBean **.

SpyBean ist eine Funktion von Spring Boot und ein Suguremono, das nur einen Teil der Verarbeitung der Klasse macht, die Sie in Mock testen möchten. Im Fall dieser Beispielquelle verspotten Sie das EmployeeRepository mit SpyBean und

--registerEmployee: Mitarbeiterregistrierungsprozess → Normale Implementierung --findEmployees: Verarbeitung der Mitarbeitertabellenanzahl → Normale Ausführung --registerNumber: Aktualisierung der Statustabelle → Fehler aufgetreten

Ich möchte eine solche Situation schaffen.

Testcode

Der Test wird ausgeführt, indem die Controller-Klasse als SpringBootTest aufgerufen wird. Die Controller-Klasse ruft die oben genannte Serviceklasse auf.

@SpringBootTest
public class EmployeesControllerTransactionTest {

    MockMvc mockMvc;

    @Autowired
    private ObjectMapper mapper;

    @Autowired
    private EmployeesController employeesController;

 // Ziel verspotten
    @SpyBean
    private EmployeeRepository employeeRepository;


    /**
 * Transaktionstest
     *
 * Wenn beim Aktualisieren der Anzahl der Mitarbeiter nach der Registrierung der Mitarbeiterinformationen in der Tabelle "Mitarbeiter" ein Fehler auftritt, <br>
 * Stellen Sie sicher, dass Sie die Registrierung von Mitarbeiterinformationen rückgängig machen
     *
     * @throws Exception
     */
    @ParameterizedTest
 @CsvSource ({"Takao Hibi, 123-4345-2352, [email protected], 3"})
    public void testTransaction(String name, String phone, String mail, int expected)
            throws Exception {

        Employee employee = new Employee(name, phone, mail);


 // Anfrage in Json-Format konvertieren
        String json = mapper.writeValueAsString(employee);

 // Fehler beim Auftreten
        doThrow(new RuntimeException()).when(employeeRepository)
                .registerNumber(Mockito.any(EmployeeNumber.class));

        this.mockMvc = MockMvcBuilders.standaloneSetup(employeesController).build();

 // Anfrage ausgeben
        MvcResult result = mockMvc.perform(
                post("/employees/register").contentType(MediaType.APPLICATION_JSON).content(json))
                .andExpect(status().isOk()).andReturn();

        String response = result.getResponse().getContentAsString();
        Employees employees = employeeRepository.findEmployees();

        System.out.println(response);
        System.out.println(employees.toString());

        EmployeeNumber actual = employees.number();

 // Da es zurückgesetzt wird, überprüfen Sie vor der Registrierung, ob es sich im Status 3 befindet
        assertEquals(expected, actual.getValue().intValue());
    }

Punkte der Testimplementierung

@SpringBootTest
public class EmployeesControllerTransactionTest {

Es ist unverzichtbar, da es nur dann DI wird, wenn SpringBootTest angehängt ist.

    @SpyBean
    private EmployeeRepository employeeRepository;

Deklarieren Sie das zu verspottende Repository.

    @ParameterizedTest
 @CsvSource ({"Takao Hibi, 123-4345-2352, [email protected], 3"})

Obwohl dies nichts mit diesem Artikel zu tun hat, können Sie mit CsvSource Variationstests mit einer Methode durchführen. Ich hatte eine lange Geschichte mit Junit4 und war beeindruckt, als mir klar wurde, dass ich das schaffen kann. Der Name wurde übrigens von Amazing Name Generator entlehnt. Es ist eine bequeme Welt geworden. (Mehr irrelevant.)

 // Fehler beim Auftreten
        doThrow(new RuntimeException()).when(employeeRepository)
                .registerNumber(Mockito.any(EmployeeNumber.class));

Hier wird deklariert, dass bei der Verarbeitung von registerNumber eine RuntimeException generiert wird.

this.mockMvc = MockMvcBuilders.standaloneSetup(employeesController).build();

Dohamari Punkt ①. Wenn Sie StandaloneSetup nicht ausführen, wird mockMvc mit nullpo gelöscht.

        MvcResult result = mockMvc.perform(
                post("/employees/register").contentType(MediaType.APPLICATION_JSON).content(json))
                .andExpect(status().isOk()).andReturn();

Dohamari Punkt ②. Wenn es nicht status (). IsOk () ist, wird es wegfliegen (devac wird nicht zurückgegeben). Ich war eine Stunde lang besorgt, als die Post-URL falsch war und 404 zurückgegeben wurde und warum die Debug-Antwort nicht auftrat.

Ergebnis der Testausführung

Als ich den Testcode ausführte, stellte sich heraus, dass es sich um einen wunderbaren grünen Balken handelte! image.png

Übrigens, wenn Sie @Transactional in der Serviceklasse entfernen, image.png

Ja, es ist ein roter Balken. Wenn sich die Anzahl der Elemente in der Mitarbeitertabelle um eins unterscheidet, tritt ein Bestätigungsfehler auf und die Transaktion kann bestätigt werden.

Schließlich

Ich werde alleine zurückblicken.

Was ich fand

Was macht man als nächstes

Recommended Posts

Führen Sie einen Transaktionsbestätigungstest mit Spring Boot durch
Formularklassenvalidierungstest mit Spring Boot
Mit Spring Boot herunterladen
Testen Sie den Controller mit Mock MVC im Spring Boot
Generieren Sie mit Spring Boot einen Barcode
Hallo Welt mit Spring Boot
Implementieren Sie GraphQL mit Spring Boot
Beginnen Sie mit Spring Boot
[JUnit 5-kompatibel] Schreiben Sie einen Test mit JUnit 5 mit Spring Boot 2.2, 2.3
Hallo Welt mit Spring Boot!
Führen Sie LIFF mit Spring Boot aus
SNS-Login mit Spring Boot
Datei-Upload mit Spring Boot
Spring Boot beginnt mit dem Kopieren
[JUnit 5] Schreiben Sie einen Validierungstest mit Spring Boot! [Parametrisierungstest]
So führen Sie UT mit Excel als Testdaten mit Spring Boot + JUnit5 + DBUnit durch
Spring Boot beginnend mit Docker
Hallo Welt mit Spring Boot
Setzen Sie Cookies mit Spring Boot
Verwenden Sie Spring JDBC mit Spring Boot
Modul mit Spring Boot hinzufügen
Erste Schritte mit Spring Boot
Erstellen Sie mit Spring Boot einen Mikrodienst
Ich habe jetzt einen Test mit Spring Boot + JUnit 5 geschrieben
Mail mit Spring Boot verschicken
Verwenden Sie die Standardauthentifizierung mit Spring Boot
gRPC auf Spring Boot mit grpc-spring-boot-Starter
Erstellen Sie eine App mit Spring Boot 2
Hot Deploy mit Spring Boot-Entwicklung
Datenbankverknüpfung mit doma2 (Spring Boot)
Schreiben Sie den Testcode mit Spring Boot
Spring Boot Programmierung mit VS Code
Bis "Hallo Welt" mit Spring Boot
Erstellen Sie eine Anfrage-App mit Spring Boot
Erhalten Sie Validierungsergebnisse mit Spring Boot
(Intellij) Hallo Welt mit Spring Boot
Erstellen Sie eine App mit Spring Boot
Google Cloud Platform mit Spring Boot 2.0.0
Verwenden Sie DBUnit für den Spring Boot-Test
Ich habe GraphQL mit Spring Boot ausprobiert
[Java] LINE-Integration mit Spring Boot
Beginnend mit Spring Boot 0. Verwenden Sie Spring CLI
Ich habe Flyway mit Spring Boot ausprobiert
Testen Sie den Spring Framework Controller mit Junit
Die Nachrichtenkooperation begann mit Spring Boot
Beispielcode zum Testen eines Spring Boot-Controllers mit MockMvc
Hallo Welt mit Eclipse + Spring Boot + Maven
Senden Sie regelmäßige Benachrichtigungen mit LineNotify + Spring Boot
HTTPS mit Spring Boot und Let's Encrypt
Versuchen Sie es mit Spring Boot mit VS-Code
Der Spring Boot @ WebMvcTest-Test aktiviert die Standardsicherheit von Spring Security
Starten Sie die Entwicklung von Webanwendungen mit Spring Boot
Starten Sie die Nginx + Spring Boot-Anwendung mit Docker-Compose
Ich habe Lazy Initialization mit Spring Boot 2.2.0 ausprobiert
Implementieren Sie CRUD mit Spring Boot + Thymeleaf + MySQL
Asynchrone Verarbeitung mit Spring Boot unter Verwendung von @Async
Implementieren Sie die Paging-Funktion mit Spring Boot + Thymeleaf
(IntelliJ + gradle) Hallo Welt mit Spring Boot
Verwenden Sie den Cache mit EhCashe 2.x mit Spring Boot