package ltd.lulz.service import io.mockk.every import io.mockk.mockk import io.mockk.slot import io.mockk.verify import java.math.BigDecimal import java.util.UUID import ltd.lulz.exception.AccountNotFoundException import ltd.lulz.model.AccountEntity import ltd.lulz.repository.AccountRepository import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import reactor.core.publisher.Mono import reactor.test.StepVerifier @Suppress("ReactiveStreamsUnusedPublisher", "MayBeConstant") class AccountServiceTest { companion object { val name: String = "some name" val amount: BigDecimal = BigDecimal.valueOf(0.01) val uuid: UUID = UUID.fromString("00000000-0000-0000-0000-000000000000") } private var repository: AccountRepository = mockk() private lateinit var service: AccountService @BeforeEach fun setUp() { service = AccountService(repository) } @Test fun `create account`() { // given val capture = slot() every { repository.save(capture(capture)) } answers { Mono.just(capture.captured.copy(id = uuid)) } // when stepped StepVerifier.create(service.create(name, amount)) .assertNext { result -> assertThat(result.id).isEqualTo(uuid) assertThat(result.name).isEqualTo(name) assertThat(result.amount).isEqualTo(amount) } .verifyComplete() verify { repository.save(any()) } } @Test fun `get by id`() { // given val capture = slot() every { repository.findById(capture(capture)) } .answers { Mono.just(AccountEntity(capture.captured, name, amount)) } // when stepped StepVerifier.create(service.getById(uuid)) .assertNext { result -> assertThat(result.id).isEqualTo(uuid) assertThat(result.name).isEqualTo(name) assertThat(result.amount).isEqualTo(amount) } .verifyComplete() verify { repository.findById(any(UUID::class)) } } @Test fun `get by id - fail`() { // given every { repository.findById(any(UUID::class)) } returns Mono.empty() // when stepped StepVerifier.create(service.getById(uuid)) .expectError(AccountNotFoundException::class.java) .verify() verify { repository.findById(any(UUID::class)) } } @Test fun `get for update by id`() { // given val capture = slot() every { repository.findByIdForUpdate(capture(capture)) } .answers { Mono.just(AccountEntity(capture.captured, name, amount)) } // when stepped StepVerifier.create(service.getForUpdateById(uuid)) .assertNext { result -> assertThat(result.id).isEqualTo(uuid) assertThat(result.name).isEqualTo(name) assertThat(result.amount).isEqualTo(amount) } .verifyComplete() verify { repository.findByIdForUpdate(any(UUID::class)) } } @Test fun `get for update by id - fail`() { // given every { repository.findByIdForUpdate(any(UUID::class)) } returns Mono.empty() // when stepped StepVerifier.create(service.getForUpdateById(uuid)) .expectError(AccountNotFoundException::class.java) .verify() verify { repository.findByIdForUpdate(any(UUID::class)) } } @Test fun `save change`() { // given val entity = AccountEntity(name = name, amount = amount) val capture = slot() every { repository.save(capture(capture)) } .answers { Mono.just(capture.captured) } // when stepped StepVerifier.create(service.save(entity)) .assertNext { result -> assertThat(result).isEqualTo(entity) } .verifyComplete() verify { repository.save(any()) } } }