user17676679
user17676679

Reputation:

How to test update methods?

I am new in unit testing and use JUnit in my Java (Spring Boot) app. I sometimes need to test update methods, but when I search on the web, there is not a proper example or suggestion. So, could you please clarify me how to test the following update method? I think this may require a different approach than testing void. I also thought that while testing first mocking the record and then update its field and then update. Finally retrieve the record again and compare the updated properties. But I think there may be more proper approach than this inexperienced one.

public PriceDTO update(UUID priceUuid, PriceRequest request) {
    Price price = priceRepository
                    .findByUuid(priceUuid)
                    .orElseThrow(() -> new EntityNotFoundException(PRICE));

    mapRequestToEntity(request, price);
    Price updated = priceRepository.saveAndFlush(price);
    
    return new PriceDTO(updated);
}

private void mapRequestToEntity(PriceRequest request, Price entity) {
    entity.setPriceAmount(request.getPriceAmount());
    // set other props
}

Upvotes: 3

Views: 5991

Answers (3)

Julien May
Julien May

Reputation: 2051

So if your only intention is to verify if you called save, then something like this is probably what you are looking for:

@ExtendWith(MockitoExtension.class)
public class ServiceTest {
    @Mock
    private PriceRepository priceRepository;
    @InjectMocks
    private Service service;

    @Test
    public void update() throws Exception {
        // Given
        Price price = new Price();
        price.setUid(UUID.randomUUID());
        price.setPriceAmount(100);

        when(priceRepository.findByUid(price.getUid()))
            .thenReturn(price);

        ArgumentCaptor<Price> priceArgument =                      
            ArgumentCaptor.forClass(Price.class);

        when(incidentRepository.saveAndFlush(priceArgument.capture()))
            .thenAnswer(iom -> iom.getArgument(0));


        // When
        PriceRequest priceRequest = new PriceRequest();
        priceRequest.setPriceAmount(123);

        PriceDTO updatedPrice = this.service.update(price.getUid(), priceUpdateRequest);

        // Then
        assertThat(priceArgument.getValue().getPriceAmount())
            .isEqualTo(123);
    }
}

Upvotes: 1

Jo&#227;o Dias
Jo&#227;o Dias

Reputation: 17510

You would need to do something along the following lines:

public class ServiceTest {

    @Mock
    private PriceRepository priceRepository;

    (...)

    @Test
    public void shouldUpdatePrice() throws Exception {
        // Arrange
        UUID priceUuid = // build the Price UUID
        PriceRequest priceUpdateRequest = // build the Price update request
        Price originalPrice = // build the original Price  
        doReturn(originalPrice).when(this.priceRepository).findByUuid(isA(UUID.class));
        doAnswer(AdditionalAnswers.returnsFirstArg()).when(this.priceRepository).saveAndFlush(isA(Price.class));

        // Act
        PriceDTO updatedPrice = this.service.update(priceUuid, priceUpdateRequest);

        // Assert
        // here you need to assert that updatedPrice is as you expect according to originalPrice and priceUpdateRequest
    }
}

Upvotes: 1

Deepak Sharma
Deepak Sharma

Reputation: 476

You need to mock the behavior of the class object priceRepository. So you will have to write something like below to begin :

// priceRepository should be mocked in the test class
Mockito.when(priceRepository.findByUuid(any(UUID.class))).thenReturn(new Price());

Upvotes: 1

Related Questions