web-dev-qa-db-fra.com

MockMVC Comment tester l'exception et le code de réponse dans le même cas de test

Je veux affirmer qu'une exception est soulevée et que le serveur renvoie une erreur de 500 serveur interne.

Pour mettre en évidence l'intention, un extrait de code est fourni:

thrown.expect(NestedServletException.class);
this.mockMvc.perform(post("/account")
            .contentType(MediaType.APPLICATION_JSON)
            .content(requestString))
            .andExpect(status().isInternalServerError());

Bien sûr, il n'a pas d'importance si j'écris isInternalServerError ou isOk. Le test passera sans distinction si une exception est jetée en dessous de la throw.except déclaration.

Comment allez-vous continuer à résoudre ce problème?

18
Farmor

Vous pouvez essayer quelque chose comme ci-dessous -

  1. Créer un correspondeur personnalisé

    public class CustomExceptionMatcher extends
    TypeSafeMatcher<CustomException> {
    
    private String actual;
    private String expected;
    
    private CustomExceptionMatcher (String expected) {
        this.expected = expected;
    }
    
    public static CustomExceptionMatcher assertSomeThing(String expected) {
        return new CustomExceptionMatcher (expected);
    }
    
    @Override
    protected boolean matchesSafely(CustomException exception) {
        actual = exception.getSomeInformation();
        return actual.equals(expected);
    }
    
    @Override
    public void describeTo(Description desc) {
        desc.appendText("Actual =").appendValue(actual)
            .appendText(" Expected =").appendValue(
                    expected);
    
    }
    }
    
  2. Déclarer un @Rule dans la classe Junit comme ci-dessous -

    @Rule
    public ExpectedException exception = ExpectedException.none();
    
  3. Utilisez la correspondance personnalisée dans le cas de test comme -

    exception.expect(CustomException.class);
    exception.expect(CustomException
            .assertSomeThing("Some assertion text"));
    this.mockMvc.perform(post("/account")
        .contentType(MediaType.APPLICATION_JSON)
        .content(requestString))
        .andExpect(status().isInternalServerError());
    

P.S.S. : J'ai fourni un pseudo-code générique que vous pouvez personnaliser selon vos besoins.

8
Bond - Java Bond

Vous pouvez faire référence à la section MVCRESULT et à l'exception éventuellement résolue et vérifiez auprès des assertions du général Junit ...

          MvcResult result = this.mvc.perform(
                post("/api/some/endpoint")
                        .contentType(TestUtil.APPLICATION_JSON_UTF8)
                        .content(TestUtil.convertObjectToJsonBytes(someObject)))
                .andDo(print())
                .andExpect(status().is4xxClientError())
                .andReturn();

        Optional<SomeException> someException = Optional.ofNullable((SomeException) result.getResolvedException());

        someException.ifPresent( (se) -> assertThat(se, is(notNullValue())));
        someException.ifPresent( (se) -> assertThat(se, is(instanceOf(SomeException.class))));
1
Eddie B

Dans votre contrôleur:

throw new Exception("Athlete with same username already exists...");

Dans votre test:

    try {
        mockMvc.perform(post("/api/athlete").contentType(contentType).
                content(TestUtil.convertObjectToJsonBytes(wAthleteFTP)))
                .andExpect(status().isInternalServerError())
                .andExpect(content().string("Athlete with same username already exists..."))
                .andDo(print());
    } catch (Exception e){
        //sink it
    }
0
Erick Audet

Si vous avez un gestionnaire d'exception et que vous souhaitez tester une exception spécifique, vous pouvez également affirmer que l'instance est valide dans l'exception résolue.

.andExpect(result -> assertTrue(result.getResolvedException() instanceof WhateverException))
0
Oluwatobiloba