Kako testirati usluge, krajnje točke i spremišta u Spring Boot-u

U ovom postu pokazat ću vam kako pisati unit testove u proljetnim programima za pokretanje.

Zašto je potrebno pisati jedinični test, potreban je još jedan članak koji će objasniti. Ali za kratko objašnjenje, reći ću vam nekoliko stvari.

Obično branim argument da je kod bez jediničnih testova mrtav kod. Jer, kada programer doda novu značajku nekom kodu koji nije obuhvaćen jediničnim testom, sklon je nadjačavanju postojećih poslovnih pravila (što ubija prethodno napisani kôd). Možda joj nije baš sklona, ​​ali možete zamisliti kakve se pogreške mogu dogoditi kada složeni projekt treba promijeniti. Jedinstveno testiranje jedini je način da zaštitite svoj kod od neovlaštenih promjena.

Zašto jedinične testne točke?

Svaki put kad napišemo krajnju točku moramo biti sigurni da nekoliko stvari ispravno funkcionira. Krajnja točka trebala bi vratiti podatke u ispravnoj strukturi i ispravno obrađivati ​​zahtjev. Možemo ga testirati ručno, što nije poželjno. Stoga pišemo jedinične testove kako bismo osigurali ispravnost naših krajnjih točaka. Postoji i drugi način za testiranje krajnjih točaka poznat pod nazivom testovi automatizacije, ali to nije tema ovog posta.

Zašto usluge jediničnog testiranja?

To bi već trebalo biti jasno, ali za svaki slučaj: moramo biti sigurni da naša poslovna logika ispravno funkcionira.

Zašto repozitoriji jedinstvenih testova?

Postoji nekoliko slučajeva za testiranje spremišta. Naravno da ne testiramo sam okvir. Ali pišemo jedinične testove kako bismo bili sigurni da su naše specifikacije ili odnosi ispravno implementirani.

Pa kako testirati kontrolere?

Sada je vrijeme da vam pokažemo kako testirati naše kontrolere u proljetnom pokretanju. Zamislimo da napišemo aplikaciju koja nam omogućuje spremanje korisnika u bazu podataka. Definiramo korisnički entitet, korisničku uslugu i kontroler.

Napomena: Primjeri prikazani u ovom postu nisu za stvarnu arhitekturu proizvodne uporabe

@Data@Entitypublic 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;}
@RestController@RequestMapping("/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); }}

Naš kontrolor ovisi o UserServiceu, ali nas ne zanima što usluga trenutno radi.

Pa sada napišite jedinstveni test za naš kontroler kako bismo bili sigurni da ispravno radi.

Ismijali smo našu uslugu jer nam ne trebaju detalji o njenoj implementaciji. Ovdje samo testiramo svoj kontroler. Ovdje koristimo MockMvcza testiranje našeg kontrolera i mapiranja objekata u svrhe serializacije.

Postavljamo našu userService.Save() metodu za vraćanje željenog korisničkog objekta. Prošli smo zahtjev za naš kontroler, a nakon što smo provjerili vratio podatke sa sljedećim liniji: andExpect(jsonPath("$.name").value(request.getName())).

Moramo koristiti i druge metode. Evo popisa metoda:

Kada pokrenemo test vidimo da je prošao.

Kako testiramo usluge?

Sada idemo testirati našu UserService. Vrlo je jednostavno testirati.

Izrugujemo se spremištu i ubrizgavamo svoje podsmijehe u UserService. Sad kad pokrenemo test, vidjet ćemo da je prošao.

Sad dodamo poslovno pravilo UserServiceu: recimo da korisnik mora imati adresu e-pošte.

Mijenjamo način spremanja u UserServiceu kako slijedi:

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

Kad ponovo pokrenemo test, vidjet ćemo neuspjeli test.

Prije nego što to popravimo, napišimo test koji zadovoljava ovaj posao.

Napisali smo novi test koji je odredio da će, ako pošaljemo nulu e-poštu, baciti NullPointerException.

Popravimo neuspjeli test dodavanjem e-pošte našem zahtjevu:

createUserRequest.setEmail("testemail");

Pokrenite oba testa:

Kako testiramo spremišta?

Sada smo došli do testiranja spremišta. Koristimo bazu podataka u memoriji h2 saTestEntityManager.

Naše spremište definirano je kako slijedi:

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

Prvo konfigurirajte h2db. Stvorite ime datoteke application.yaml u test -> path path:

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

I prvo napišimo osnovni test za naše spremište: spremite korisnika i dohvatite ga:

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

Kad ga pokrenemo, vidjet ćemo gomilu rezultata konzole, a također i test koji prolazi:

Ajmo sada dodati još jednu metodu u naše spremište za traženje korisnika putem e-pošte:

Optional findByEmail(String email);

I napišite još jedan test:

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

Kad bacimo pogled na konzolu nakon pokretanja testa, vidjet ćemo SQL koji generira hibernate:

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

Zasada je dobro. Osnove jediničnog testiranja pokrili smo opružnim prtljažnikom.

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.