javaspring-bootjunitjunit5data-jpa-test

Java unit test case support for particular id value only not support for other integer values


I wanted to write a unit test for an update query for one of my JpaRepository. following is my implementation.

public interface UserRepository extends JpaRepository<User, Integer> {

    @Modifying
    @Query("update User u set u.active = false where u.userId = :userId")
    void updateEmployee(Integer userId);

.......
}

In the test case, I wrote like below,

@DataJpaTest
class UserAppRepoTest {

    @Autowired
    private EntityManager entityManager;
    
    @Autowired
    private UserRepository userRepository;

    public void flushAndClear() {
        entityManager.flush();
        entityManager.clear();
    }

    @Test
    public void updateUserRecord() {
        User user = new User();
        user.setUserId(2);
        entityManager.merge(user);
        flushAndClear();
        
        userRepository.updateEmployee(user.getUserId());

        User result = entityManager.find(User.class, user.getUserId());
        assertEquals(false, result.getActive());
    }
}

But here the test case is only passed for user.setUserId(2). If the userId is set to other integer values, the test case fails. I could not find that, why it is happening only for userId = 2. The user object is getting null(result = null) for other integers. For example, user.setUserId(1), user.setUserId(3), .... and so on. I expect to know that I am following correct way of writing test case for a particular query?


Solution

  • The query under test is an update, so the entity must already exist. Indeed, the test setup from your code

    User user = new User();
    user.setUserId(2);
    entityManager.merge(user);
    

    adds a user with ID 2. That is the only User instance entityManager is aware of, so referencing any other userId will return null.

    Also, the test does this assertion:

    assertEquals(false, result.getActive());
    

    But looking at the test setup again:

    User user = new User();
    user.setUserId(2);
    entityManager.merge(user);
    

    that user is probably already not active (unless the constructor sets a user to active). So the test setup should probably be similar to:

    User user = new User();
    user.setUserId(2);
    user.setActive(true); // add to the test setup
    entityManager.merge(user);
    

    then the assertion:

    assertEquals(false, result.getActive());
    

    verifies the update query worked as expected on the user.

    Perhaps add two users in the test setup, both as active. Then can verify user with ID 2 is no longer active and other user is still active. That would verify the query where clause.