Palvelujen, päätepisteiden ja arkistojen testaaminen Spring Boot -sovelluksessa

Tässä viestissä näytän sinulle kuinka kirjoittaa yksikötestit kevään käynnistyssovelluksissa.

Miksi yksikkötesti on tarpeen kirjoittaa, tarvitaan toinen artikkeli. Mutta lyhyeksi selitykseksi kerron sinulle useita asioita.

Puolustan tavallisesti väitettä, jonka mukaan koodi ilman yksikötestejä on kuollut koodi. Koska kehittäjä lisää uuden ominaisuuden johonkin koodiin, jota yksikötesti ei kata, se on taipuvainen korvaamaan olemassa olevat liiketoimintasäännöt (mikä tappaa aiemmin kirjoitetun koodin). Ehkä se ei ole altis sille, mutta voit kuvitella, mitä virheitä voi esiintyä, kun monimutkainen projekti on muutettava. Yksikkötestaus on ainoa tapa suojata koodi rikkoutumattomilta muutoksilta.

Miksi yksikkötestipisteet?

Joka kerta kun kirjoitamme päätepisteen, meidän on varmistettava, että useat asiat toimivat oikein. Päätepisteen tulisi palauttaa tiedot oikeassa rakenteessa ja käsitellä pyyntöä oikein. Voimme testata sen manuaalisesti, mikä ei ole suositeltavaa. Joten kirjoitamme yksikkötestejä varmistaaksemme, että päätepisteemme toimivat oikein. On myös toinen tapa testata päätepisteitä, joita kutsutaan automaatiotesteiksi, mutta se ei ole tämän viestin aihe.

Miksi yksikkötestauspalvelut?

Sen pitäisi olla jo selvää, mutta vain siinä tapauksessa: meidän on oltava varmoja, että liiketoimintalogiikkamme toimii oikein.

Miksi yksikkötestivarastot?

Tietovarastojen testaamiseksi on useita tapauksia. Tietysti emme testaa itse kehystä. Mutta kirjoitamme yksikkötestejä varmistaaksemme, että määrityksemme tai suhteemme on toteutettu oikein.

Joten miten testataan ohjaimia?

Nyt on aika näyttää, kuinka testata ohjaimia keväällä. Kuvitellaan, että kirjoitamme sovelluksen, jonka avulla voimme tallentaa käyttäjiä tietokantaan. Määritämme käyttäjäentiteetin, käyttäjäpalvelun ja ohjaimen.

Huomaa: Tässä viestissä esitetyt esimerkit eivät ole todellista tuotantokäyttöarkkitehtuuria

@[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); }}

Ohjaimemme on riippuvainen UserServicestä, mutta meitä ei kiinnosta, mitä palvelu tekee juuri nyt.

Joten nyt kirjoitetaan ohjaintestillemme yksikkötesti varmistaaksemme, että se toimii oikein.

Pilkkasimme palvelumme, koska emme tarvitse sen käyttöönottotietoja. Testaamme vain ohjainta täällä. Testaamme MockMvctässä ohjainta ja objektikartoitinta sarjoitustarkoituksiin.

Asetamme userService.Save() menetelmän palauttaa haluttu käyttäjäobjekti. Ohitimme pyyntö meille ohjaimeen ja sen jälkeen pyysimme palautetun datan seuraava rivi: andExpect(jsonPath("$.name").value(request.getName())).

Meillä on myös muita menetelmiä. Tässä on luettelo menetelmistä:

Kun suoritamme testin, näemme sen läpäisevän.

Kuinka testaamme palveluja?

Nyt menemme testaamaan UserServicea. Se on melko helppo testata.

Pilkataan arkistoa ja injektoidaan pilkkuja UserServiceen. Nyt kun suoritamme testin, näemme sen läpäisevän.

Lisätään nyt liikesääntö UserServiceen: sanotaan, että käyttäjällä on oltava sähköpostiosoite.

Muutamme tallennusmenetelmää UserServicessa seuraavasti:

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;}

Kun suoritamme testin uudelleen, näemme epäonnistuneen testin.

Ennen kuin korjaamme sen, kirjoitetaan testi, joka tyydyttää tätä yritystä.

Kirjoitimme uuden testin, jossa määriteltiin, että jos lähetämme tyhjän sähköpostin, se heittää NullPointerException.

Korjataan epäonnistunut testi lisäämällä sähköposti pyyntömme:

createUserRequest.setEmail("testemail");

Suorita molemmat testit:

Kuinka testaamme arkistoja?

Nyt olemme tulleet testaamaan arkistoja. Käytämme muistissa olevaa h2-tietokantaaTestEntityManager.

Tietovarastomme on määritelty seuraavasti:

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

Määritä ensin h2db. Luo tiedostonimi application.yaml testissä -> resurssien polku:

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

Ja ensin kirjoitetaan arkistollemme perustesti: tallenna käyttäjä ja hae se:

@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); }}

Kun suoritamme sen, näemme joukon konsolilähtöjä ja myös testipassimme:

Lisätään nyt toinen menetelmä arkistoon käyttäjän etsimiseksi sähköpostitse:

Optional findByEmail(String email);

Ja kirjoita toinen testi:

@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);}

Kun katsomme konsolia testin suorittamisen jälkeen, näemme horrostilan luoman SQL: n:

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=?

Toistaiseksi niin hyvä. Olemme tarkastelleet yksikkötestauksen perusteet jousella.

Nyt sinulla ei ole tekosyitä olla kirjoittamatta yksikkötestejä! Toivon, että sinulle on selvää, kuinka kirjoitat yksikkötestejä erilaisiin tarkoituksiin.