Test - Quick Reference

Mockito

Mockito is a popular mocking framework for Java that allows developers to create mock objects in automated unit tests.

Basic Concepts

Unit Tests

How to test void methods


@Mock
private MyService myService;

@Test
void testSomething() {
    // ARRANGE
    var trackingBuyer = Tracking.builder()
        .identifier(tracking.getIdentifier())
        .deliveryInfo(tracking.getDeliveryInfo())
        .auditInformation(tracking.getAuditInformation())
        .buyer(Buyer.builder()
                    .buyerId("1313")
                    .legalDocumentNumber("00589076250001")
                    .fiscalType(PersonType.NATURAL_PERSON)
                    .build())
        .paymentInfo(tracking.getPaymentInfo())
        .orderDate(Instant.now())
        .flowType(tracking.getFlowType())
        .items(tracking.getItems())
        .build();

    doNothing().when(myService).receivePrePaidCardDelivery(tracking);

    // ACT
    myService.receivePrePaidCardDelivery(trackingBuyer);

    // ASSERT
    verify(myService).receivePrePaidCardDelivery(trackingBuyer);

}

How to test exceptions

@ExtendWith(MockitoExtension.class)
class EmbeddedProductConfigurationServiceTest {

    @Mock
    MessageService messages;

    @Mock
    EmbeddedProductConfigurationRepository embeddedProductConfigurationRepository;

    @Mock
    ProductFacade productFacade;

    @Mock
    DomainFacade domainFacade;

    @InjectMocks
    EmbeddedProductConfigurationService service;

    @Test
    void testProductConfigEmptyRules() {
        var body = new EmbeddedProductConfigurationRequest();
        body.setProductId("");
        body.setRules(Set.of());

        assertThrows(BusinessException.class, () -> service.createEmbeddedProductConfig(body));
    }

    @Test
    void testProductConfigValidRules() throws Exception {
        var dto = new EmbeddedProductConfigurationRequest();
        dto.setProductId("1s");
        dto.setRules(Set.of(Map.of("merchant_type", Set.of("internal"))));
        dto.setAuditInformation(new AuditInformation(Instant.now(), Instant.now()));
        dto.setSituation(new EmbeddedProductConfigurationStatus(EmbeddedProductStatus.ACTIVATED));
        BeanHelper.fillPrincipal(dto.getAuditInformation());

        var domainData = new DomainData();
        domainData.setCode("internal");
        when(domainFacade.findByType(anyString())).thenReturn(Optional.of(List.of(domainData)));
        when(productFacade.findProductById("1s")).thenReturn(Optional.of(buildProduct()));

        var entity = MapperHelper.convertDTOToEntity(dto, EmbeddedProductConfiguration.class);
        lenient().when(embeddedProductConfigurationRepository.save(Mockito.any(EmbeddedProductConfiguration.class))).thenReturn(entity);

        var resp = service.createEmbeddedProductConfig(dto);

        Assertions.assertNotNull(resp);
    }

    @Test
    void testAllowEmbedInvalid() {
        var dto = new EmbeddedProductConfigurationRequest();
        dto.setProductId("1s");
        dto.setRules(Set.of(Map.of("merchant_type", Set.of("internal"))));

        var product = buildProduct();
        var productServiceDomain = (ProductServiceDomain) product;
        productServiceDomain.setAllowsEmbedding(false);

        when(productFacade.findProductById("1s")).thenReturn(Optional.of(productServiceDomain));

        assertThrows(BusinessException.class, () -> service.createEmbeddedProductConfig(dto));
    }
}

Integration Tests


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.*;

import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertSame;

@SpringBootTest(classes = App.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class AdapterPaymentPluginControllerITest {

    @LocalServerPort
    int port;

    final String path = "/adapter-payments-plugins/";

    @Autowired
    TestRestTemplate restTemplate;

    String accessToken;

    @BeforeEach
    void setUp() throws JsonProcessingException {
        var u = "https://example.com/v1/token";
        var clientId = "";
        var secret = "";
        var channel = "";
        var scope = "read";
        var h = new HttpHeaders();
        h.setAll(Map.of("client_id", clientId, "client_secret", secret, "channel", channel, "scope", scope));
        h.setContentType(MediaType.APPLICATION_JSON);
        var b = "{\"name\": \"tiago\", \"login\": \"username\", \"system\": \"\", \"scope\": \"\"}";
        var e = new HttpEntity<>(b, h);
        var r = restTemplate.exchange(u, HttpMethod.POST, e, String.class);
        accessToken = (String) new ObjectMapper().readValue(r.getBody(), Map.class).get("access_token");
    }

    @Test
    void testEndpointForbidden() {
        String url = "http://localhost:" + port + path + "/1";

        var res = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null, null), String.class);

        assertThat(res).isNotNull();
        assertSame(HttpStatus.FORBIDDEN, res.getStatusCode());
    }

    @Test
    void testEndpointNotFound() {
        String url = "http://localhost:" + port + path + "/1";
        var headers = new HttpHeaders();
        headers.setAll(Map.of("Authorization", accessToken));
        headers.setContentType(MediaType.APPLICATION_JSON);

        var res = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null, headers), String.class);

        assertThat(res).isNotNull();
        assertSame(HttpStatus.NOT_FOUND, res.getStatusCode());
    }
}