Hogyan tesztelhetjük a szolgáltatásokat, a végpontokat és a tárakat a Spring Boot alkalmazásban

Ebben a bejegyzésben megmutatom, hogyan kell írni az egység teszteket a tavaszi rendszerindító alkalmazásokban.

Miért szükséges az egység tesztet írni, egy másik cikk magyarázatát igényli. De egy rövid magyarázatért elmondok neked több dolgot.

Általában azzal az érvvel védek, hogy az egységteszt nélküli kód a hibakód. Mivel, ha egy fejlesztő új funkciót ad hozzá egy olyan kódhoz, amelyre nem vonatkozik az egységteszt, akkor hajlamos felülírni a meglévő üzleti szabályokat (ami megöli az előzőleg írt kódot). Lehet, hogy ez nem éppen hajlamos rá, de el tudja képzelni, milyen hibák léphetnek fel, ha egy összetett projektet meg kell változtatni. Az egység tesztelése az egyetlen módja annak, hogy megvédje kódját a változások megsértésétől.

Miért egység teszt végpontok?

Minden alkalommal, amikor végpontot írunk, biztosnak kell lennünk abban, hogy több dolog megfelelően működik. A végpontnak vissza kell adnia az adatokat a megfelelő struktúrában, és helyesen kell kezelnie a kérést. Manuálisan tesztelhetjük, ami nem előnyösebb. Tehát egység teszteket írunk annak érdekében, hogy a végpontjaink megfelelően működjenek. Van egy másik módja is a végpontok tesztelésének, az úgynevezett automatizálási teszteknek, de ez nem a jelen bejegyzés tárgya.

Miért egység teszt szolgáltatások?

Ennek már világosnak kell lennie, de csak arra az esetre: biztosnak kell lennünk abban, hogy üzleti logikánk megfelelően működik.

Miért kell az egységteszteket tárolni?

A tárak tesztelésére több esetben van lehetőség. Magát a keretet természetesen nem teszteljük. De azért írunk egységteszteket, hogy megbizonyosodjunk arról, hogy specifikációinkat vagy kapcsolatainkat helyesen hajtották-e végre.

Tehát hogyan teszteljük a vezérlőket?

Itt az ideje, hogy megmutassuk, hogyan tesztelhetjük vezérlőinket a tavaszi indításkor. Képzeljük el, hogy írunk egy alkalmazást, amely lehetővé teszi számunkra a felhasználók adatbázisba mentését. Meghatározunk egy felhasználói entitást, egy felhasználói szolgáltatást és egy vezérlőt.

Megjegyzés: Az ebben a bejegyzésben bemutatott példák nem valódi gyártási felhasználású architektúrára vonatkoznak

@[email protected] class User { @Id @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator") @Column(name = "id", columnDefinition = "BINARY(16)") private UUID id; private String name; private String email; private int age;}
@Datapublic class CreateUserRequest { private String name; private String email; private int age;}
@[email protected]("/users")public class UserController { UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; } @PostMapping public ResponseEntity createUser(@RequestBody CreateUserRequest request) { User created = userService.save(request); return ResponseEntity.ok(created); }}

Vezérlőnk függ a UserService-től, de nem érdekel, hogy a szolgáltatás mit csinál most.

Tehát most írjunk egy egység tesztet a vezérlőnknek, hogy megbizonyosodhassunk róla, hogy megfelelően működik.

Kicsúfoltuk szolgáltatásunkat, mert nincs szükségünk a megvalósítás részleteire. Csak itt teszteljük a vezérlőnket. Az általunk használt MockMvcitt, hogy próbára tegyük vezérlő és objektum leképező sorozatprogramozásának célra.

Beállítottuk userService.Save() módszerünket a kívánt felhasználói objektum visszaküldésére. Mentünk egy kérést a vezérlő és utána megnéztük a visszaküldött adatok a következő sort: andExpect(jsonPath("$.name").value(request.getName())).

Más módszereket is alkalmazhatunk. Itt van a módszerek listája:

Amikor lefuttatjuk a tesztet, látjuk, hogy az sikeres.

Hogyan teszteljük a szolgáltatásokat?

Most megyünk tesztelni a UserService-t. Nagyon egyszerű tesztelni.

Gúnyolódunk az adattárból, és injekciókat juttatunk a UserService-be. Most, amikor lefuttatjuk a tesztet, látni fogjuk, hogy sikeres.

Most adjunk hozzá üzleti szabályt a UserService szolgáltatáshoz: tegyük fel, hogy a felhasználónak rendelkeznie kell e-mail címmel.

Az alábbiakban megváltoztatjuk a mentési módszert a UserService szolgáltatásban:

public User save(CreateUserRequest request) { requireNonNull(request.getEmail()); User user = new User(); user.setName(request.getName()); user.setEmail(request.getEmail()); user.setAge(request.getAge()); userRepository.save(user); return user;}

Amikor újra lefuttatjuk a tesztet, sikertelen tesztet fogunk látni.

Mielőtt kijavítanánk, írjunk egy tesztet, amely kielégíti ezt az üzletet.

Írtunk egy új tesztet, amely meghatározta, hogy ha null e-mailt küldünk, az dob NullPointerException.

Javítsuk ki a sikertelen tesztet egy e-mail hozzáadásával a kérésünkhöz:

createUserRequest.setEmail("testemail");

Futtassa mindkét tesztet:

Hogyan teszteljük az adattárakat?

Most rátértünk a tárak tesztelésére. A memóriában h2 adatbázist használunk aTestEntityManager.

Adattárunk az alábbiak szerint van meghatározva:

@Repositorypublic interface UserRepository extends JpaRepository, JpaSpecificationExecutor { Optional findById(UUID id);}

Először konfigurálja a h2db-t. Hozza létre az application.yaml fájlnevet a tesztben -> erőforrások elérési útja:

spring: application: name: Spring Boot Rest API datasource: type: com.zaxxer.hikari.HikariDataSource url: "jdbc:h2:mem:test-api;INIT=CREATE SCHEMA IF NOT EXISTS dbo\\;CREATE SCHEMA IF NOT EXISTS definitions;DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MODE=MSSQLServer" name: password: username: initialization-mode: never hikari: schema: dbo jpa: database: H2 database-platform: org.hibernate.dialect.H2Dialect show-sql: true hibernate: ddl-auto: create-drop test: database: replace: none

Először írjunk egy alapvető tesztet a tárunkhoz: mentse el a felhasználót és töltse le:

@RunWith(SpringRunner.class)@DataJpaTestpublic class UserRepositoryTest { @Autowired TestEntityManager entityManager; @Autowired UserRepository sut; @Test public void it_should_save_user() { User user = new User(); user.setName("test user"); user = entityManager.persistAndFlush(user); assertThat(sut.findById(user.getId()).get()).isEqualTo(user); }}

Amikor futtatjuk, látni fogunk egy csomó konzol kimenetet, és teszt tesztjeinket is:

Most adjunk hozzá egy másik módszert a tárunkba, hogy e-mailben keressünk felhasználót:

Optional findByEmail(String email);

És írjon még egy tesztet:

@Testpublic void it_should_find_user_byEmail() { User user = new User(); user.setEmail("[email protected]"); user = entityManager.persistAndFlush(user); assertThat(sut.findByEmail(user.getEmail()).get()).isEqualTo(user);}

Amikor a teszt futtatása után megnézzük a konzolt, látni fogjuk a hibernálás által generált SQL-t:

SELECT user0_.id AS id1_1_,user0_.age AS age2_1_,user0_.email AS email3_1_,user0_.name AS name4_1_FROM user user0_WHERE user0_.email=?

Eddig jó. Az egység tesztelésének alapjait a rugós csomagtartóval ismertettük.

Now you don’t have any excuses to not write unit tests! I hope it is clear to you to how to write unit tests for different kinds of purposes.