test: Add unit tests for PriceService and PriceRepositoryAdapter

This commit is contained in:
bedroomghost 2025-04-20 18:02:22 +02:00
parent 92871f0819
commit 18866635ab
5 changed files with 205 additions and 19 deletions

View File

@ -1,2 +1,33 @@
# web-price
Prices web service (web-price)
===================================
Web service for obtaining the price of a product given a date, the product id and the brand id.
## Requirements
- Java 21
- Maven
## Development
1. Local installation of the project
```
mvn clean install
```
2. Run the app from the project root with:
```
mvn clean spring-boot:run -pl boot -Dspring-boot.run.profiles=local
```
or navigating to the `boot` directory of the project:
```
mvn clean spring-boot:run -Dspring-boot.run.profiles=local
```
3. Service should be ready to receive requests at http://localhost:8080/price with OpenAPI docs available at http://localhost:8080/swagger-ui/index.html
## Running Tests
To run all tests in the project:
```bash
mvn test
```

View File

@ -0,0 +1,77 @@
package com.techivw.webprice.application.services;
import com.techivw.webprice.application.exceptions.NotFoundException;
import com.techivw.webprice.application.ports.in.PriceServicePort;
import com.techivw.webprice.application.ports.out.PriceRepositoryPort;
import com.techivw.webprice.domain.Price;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
@ExtendWith(SpringExtension.class)
class PriceServiceTest {
@Mock
private PriceRepositoryPort priceRepositoryPort;
private PriceServicePort priceService;
private final LocalDateTime TEST_DATE = LocalDateTime.parse("2023-01-01T12:00:00");
private final Long TEST_PRODUCT_ID = 35455L;
private final Long TEST_BRAND_ID = 1L;
@BeforeEach
void setUp() {
priceService = new PriceService(priceRepositoryPort);
}
@Test
void shouldReturnPriceWhenPriceExists() {
Price expectedPrice = createPrice();
when(priceRepositoryPort.findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(
eq(TEST_DATE), eq(TEST_PRODUCT_ID), eq(TEST_BRAND_ID)))
.thenReturn(Optional.of(expectedPrice));
Price result = priceService.getPriceWithHighestPriorityByDateTimeAndProductIdAndBrandId(
TEST_DATE, TEST_PRODUCT_ID, TEST_BRAND_ID);
assertNotNull(result);
assertEquals(expectedPrice.getProductId(), result.getProductId());
assertEquals(expectedPrice.getPrice(), result.getPrice());
}
@Test
void shouldThrowNotFoundExceptionWhenPriceDoesNotExist() {
when(priceRepositoryPort.findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(
any(LocalDateTime.class), anyLong(), anyLong()))
.thenReturn(Optional.empty());
assertThrows(NotFoundException.class, () ->
priceService.getPriceWithHighestPriorityByDateTimeAndProductIdAndBrandId(
TEST_DATE, TEST_PRODUCT_ID, TEST_BRAND_ID));
}
private Price createPrice() {
return Price.builder()
.brandId(TEST_BRAND_ID)
.productId(TEST_PRODUCT_ID)
.startDate(TEST_DATE.minusDays(1))
.endDate(TEST_DATE.plusDays(1))
.priceList(1L)
.price(BigDecimal.valueOf(35.50))
.priority(1)
.currency("EUR")
.build();
}
}

View File

@ -16,12 +16,6 @@
<name>rest-api</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.techivw</groupId>
<artifactId>domain</artifactId>
@ -34,16 +28,4 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-javaagent:${settings.localRepository}/net/bytebuddy/byte-buddy-agent/1.15.11/byte-buddy-agent-1.15.11.jar</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,78 @@
package com.techivw.webprice.infrastructure.repositories.adapters;
import com.techivw.webprice.domain.Price;
import com.techivw.webprice.infrastructure.repositories.PriceEntityJPARepository;
import com.techivw.webprice.infrastructure.repositories.model.PriceEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class PriceRepositoryAdapterTest {
@Mock
private PriceEntityJPARepository repository;
private PriceRepositoryAdapter adapter;
private final LocalDateTime TEST_DATE = LocalDateTime.parse("2023-01-01T12:00:00");
private final Long TEST_PRODUCT_ID = 35455L;
private final Long TEST_BRAND_ID = 1L;
@BeforeEach
void setUp() {
adapter = new PriceRepositoryAdapter(repository);
}
@Test
void shouldReturnPriceWhenPriceEntityExists() {
PriceEntity priceEntity = createSamplePriceEntity();
when(repository.findPriceByDateTimeAndProductIdAndBrandId(
eq(TEST_DATE), eq(TEST_PRODUCT_ID), eq(TEST_BRAND_ID)))
.thenReturn(Optional.of(priceEntity));
Optional<Price> result = adapter.findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(
TEST_DATE, TEST_PRODUCT_ID, TEST_BRAND_ID);
assertTrue(result.isPresent());
Price price = result.get();
assertEquals(TEST_PRODUCT_ID, price.getProductId());
assertEquals(TEST_BRAND_ID, price.getBrandId());
assertEquals(BigDecimal.valueOf(35.50), price.getPrice());
}
@Test
void shouldReturnEmptyOptionalWhenPriceEntityDoesNotExist() {
when(repository.findPriceByDateTimeAndProductIdAndBrandId(
any(LocalDateTime.class), anyLong(), anyLong()))
.thenReturn(Optional.empty());
Optional<Price> result = adapter.findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(
TEST_DATE, TEST_PRODUCT_ID, TEST_BRAND_ID);
assertFalse(result.isPresent());
}
private PriceEntity createSamplePriceEntity() {
PriceEntity entity = new PriceEntity();
entity.setBrandId(TEST_BRAND_ID);
entity.setProductId(TEST_PRODUCT_ID);
entity.setStartDate(TEST_DATE.minusDays(1));
entity.setEndDate(TEST_DATE.plusDays(1));
entity.setPriceList(1L);
entity.setPrice(BigDecimal.valueOf(35.50));
entity.setPriority(1);
entity.setCurrency("EUR");
return entity;
}
}

18
pom.xml
View File

@ -51,5 +51,23 @@
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-javaagent:${settings.localRepository}/net/bytebuddy/byte-buddy-agent/1.15.11/byte-buddy-agent-1.15.11.jar</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>