Search code examples
javaspring-bootunit-testingjunitjunit5

UnitTest final UUID changes within the test if @BeforeEach#repository.save() is executed


I have an OrderRepositoryTest code below where I am trying to get the valid order by Uuid

OrderRepositoryTest

@DataJpaTest
@ExtendWith(SpringExtension.class)
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class OrderRepositoryTest {

    private static final Logger logger = LoggerFactory.getLogger(OrderRepositoryTest.class);

    @Autowired
    OrderRepository orderRepository;

    private static final UUID id2;

    Order order2 = setOrder2();

    static {
        id2 = UUID.randomUUID();
    }

    @BeforeEach
    public void setUp() {
        orderRepository.save(order2);
    }

    @AfterEach
    public void tearDown() {
        orderRepository.deleteAll();
    }

    @Test
    public void OrderRepositoryTest_getValidOrder() {

        Assertions.assertThat(id2).isEqualTo(order2.getUuid());

        // TODO unit test get valid order using orderRepository.findOrderByUuid()
    }

    public Order setOrder2() {

        return Order
                .builder()
                .uuid(id2)
                .build();
    }

}

Order

@Getter
@Setter
@Builder
@ToString
@Jacksonized
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "orders")
public class Order {

    @Valid

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    UUID uuid;

    // TODO other columns
}

OrderRepository

public interface OrderRepository extends JpaRepository<Order, UUID> {
    Optional<Order> findOrderByUuid(UUID uuid);
}

I would get error: Expected [correct_uuid] but was [wrong_uuid]. However, if I comment the orderRepository.save(order2); and orderRepository.deleteAll();, both uuids matches and the test will pass.

My expected result should be even if I run the .save() and .delete() method, since the UUID id2 is a final variable, it should always be the same.

Note:

I initially tries assigning the id2 as: private static final UUID id2 = UUID.randomUUID(); but this failed too.

Note2:

I could do the following:

@Test
public void OrderRepositoryTest_getValidOrder() {

    UUID order2UUid = order2.getUuid();

    // TODO orderRepository.findOrderByUuid(order2UUid)
}

This will pass the test but I feel that I should be able to use the initially assigned UUID instead thus I did not do it like this.


Solution

  • The "problem" is that the id is auto generated, because of the annotation @GeneratedValue. When you call 'orderRepository.save(order2);' the id value you passed when building the order is ignored and a new UUID is automatically generated.

    You should not set the id for order, since it's auto generated by the persistence layer.