Ricerca…


Come testare una semplice applicazione di avvio a molla

Abbiamo un'applicazione di avvio Spring di esempio che memorizza i dati dell'utente in MongoDB e stiamo utilizzando i servizi di Rest per recuperare i dati

Prima c'è una classe di dominio, ad esempio POJO

@Document
public class User{
    @Id
    private String id;

    private String name;

}

Un repository corrispondente basato su Spring Data MongoDB

public interface UserRepository extends MongoRepository<User, String> {
}

Quindi il nostro controller utente

@RestController
class UserController {
 
    @Autowired
    private UserRepository repository;
 
    @RequestMapping("/users")
    List<User> users() {
        return repository.findAll();
    }
 
    @RequestMapping(value = "/Users/{id}", method = RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    void delete(@PathVariable("id") String id) {
        repository.delete(id);
    }
 
    // more controller methods
}

E infine la nostra applicazione Spring Boot

@SpringBootApplication
public class Application {
    public static void main(String args[]){
     SpringApplication.run(Application.class, args);
    }
}

Se, diciamo che John Cena, The Rock e TripleHHH erano gli unici tre utenti nel database, una richiesta a / utenti avrebbe dato la seguente risposta:

$ curl localhost:8080/users
[{"name":"John Cena","id":"1"},{"name":"The Rock","id":"2"},{"name":"TripleHHH","id":"3"}]

Ora per testare il codice verificheremo che l'applicazione funzioni

@RunWith(SpringJUnit4ClassRunner.class)   // 1
@SpringApplicationConfiguration(classes = Application.class)   // 2
@WebAppConfiguration   // 3
@IntegrationTest("server.port:0")   // 4
public class UserControllerTest {

    @Autowired   // 5
    UserRepository repository;

    User cena;
    User rock;
    User tripleHHH;

    @Value("${local.server.port}")   // 6
    int port;

    @Before
    public void setUp() {
        // 7
        cena = new User("John Cena");
        rock = new User("The Rock");
        tripleHHH = new User("TripleHH");

        // 8
        repository.deleteAll();
        repository.save(Arrays.asList(cena, rock, tripleHHH));

        // 9
        RestAssured.port = port;
    }

    // 10
    @Test
    public void testFetchCena() {
        String cenaId = cena.getId();

        when().
                get("/Users/{id}", cenaId).
        then().
                statusCode(HttpStatus.SC_OK).
                body("name", Matchers.is("John Cena")).
                body("id", Matchers.is(cenaId));
    }

    @Test
    public void testFetchAll() {
        when().
                get("/users").
        then().
                statusCode(HttpStatus.SC_OK).
                body("name", Matchers.hasItems("John Cena", "The Rock", "TripleHHH"));
    }

    @Test
    public void testDeletetripleHHH() {
        String tripleHHHId = tripleHHH.getId();

        when()
                .delete("/Users/{id}", tripleHHHId).
        then().
                statusCode(HttpStatus.SC_NO_CONTENT);
    }
}

Spiegazione

  1. Come qualsiasi altro test basato su Spring, abbiamo bisogno di SpringJUnit4ClassRunner per SpringJUnit4ClassRunner un contesto applicativo.
  2. L'annotazione @SpringApplicationConfiguration è simile all'annotazione @ContextConfiguration in quanto viene utilizzata per specificare i contesti di applicazione da utilizzare nel test. Inoltre, attiverà la logica per la lettura delle configurazioni, delle proprietà e così via di Spring Boot.
  3. @WebAppConfiguration deve essere presente per dire a Spring che un WebApplicationContext deve essere caricato per il test. Fornisce anche un attributo per specificare il percorso alla radice dell'applicazione web.
  4. @IntegrationTest viene utilizzato per indicare a Spring Boot che il server Web incorporato deve essere avviato. Fornendo coppie di nomi / valori separati da due punti o da due punti, qualsiasi variabile d'ambiente può essere sovrascritta. In questo esempio, "server.port:0" sostituirà l'impostazione della porta predefinita del server. Normalmente, il server inizia a utilizzare il numero di porta specificato, ma il valore 0 ha un significato speciale. Se specificato come 0, indica a Spring Boot di eseguire la scansione delle porte sull'ambiente host e avviare il server su una porta casuale disponibile. Ciò è utile se disponiamo di servizi diversi che occupano porte diverse sui computer di sviluppo e sul build server che potrebbero potenzialmente entrare in collisione con la porta dell'applicazione, nel qual caso l'applicazione non verrà avviata. In secondo luogo, se creiamo più test di integrazione con diversi contesti applicativi, possono anche scontrarsi se i test vengono eseguiti contemporaneamente.
  5. Abbiamo accesso al contesto dell'applicazione e possiamo utilizzare l'autowiring per iniettare qualsiasi bean Spring.
  6. Il valore @Value("${local.server.port}”) verrà risolto sul numero di porta effettivo che viene utilizzato.
  7. Creiamo alcune entità che possiamo usare per la convalida.
  8. Il database MongoDB viene cancellato e reinizializzato per ciascun test in modo da essere sempre convalidati rispetto a uno stato noto. Poiché l'ordine dei test non è definito, è probabile che il test testFetchAll () non riesca se viene eseguito dopo il test testDeletetripleHHH ().
  9. Forniamo a Rest Assured l'uso della porta corretta. È un progetto open source che fornisce un DSL Java per testare i servizi restful
  10. I test sono implementati usando Rest Assured. possiamo implementare i test utilizzando TestRestTemplate o qualsiasi altro client http, ma io utilizzo Rest Assured perché possiamo scrivere documentazione concisa usando RestDocs

Caricare file yaml [o proprietà] diversi o sovrascrivere alcune proprietà

Quando usiamo @SpringApplicationConfiguration userà la configurazione da application.yml [proprietà] che in determinate situazioni non è appropriata. Quindi per sovrascrivere le proprietà possiamo usare @TestPropertySource annotazione @TestPropertySource .

@TestPropertySource(
        properties = {
                "spring.jpa.hibernate.ddl-auto=create-drop",
                "liquibase.enabled=false"
        }
)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTest{

    // ...

}

Possiamo usare l'attributo properties di @TestPropertySource per sovrascrivere le proprietà specifiche che vogliamo. Nell'esempio precedente stiamo spring.jpa.hibernate.ddl-auto override della proprietà spring.jpa.hibernate.ddl-auto su create-drop . E liquibase.enabled a false .

Caricamento di file yml diversi

Se si desidera caricare completamente un file yml diverso per il test, è possibile utilizzare l'attributo locations su @TestPropertySource .

@TestPropertySource(locations="classpath:test.yml")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTest{

    // ...

}

In alternativa opzioni

Opzione 1:

Puoi anche caricare diversi file yml inserendo un file yml nella directory test > resource

Opzione 2:

Utilizzo dell'annotazione @ActiveProfiles

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@ActiveProfiles("somename")
public class MyIntTest{
}

Puoi vedere che stiamo usando @ActiveProfiles annotazione @ActiveProfiles e stiamo passando il somename come valore.

Crea un file chiamato application-somename.yml e il test caricherà questo file.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow