-1

There is a basic CRUD API, and I want to test the UserServiseImpl.java class in its Service layer. In UserServiseImpl, entities are retrieved with

userRepository.findAll(query)

as shown below, and I want to mock this.

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
UserSpecification spec = new UserSpecification();
Specification<User> query = Specification.where(spec.userIdEqual(spec.userIdEqual(userId)))
                    .and(spec.nameContains(target.getName()))
                    .and(spec.startDateGreaterThanEqual(target.getStartDate()))
                    .and(spec.endDateLessThanEqual(target.getEndDate()))

       List<User> user = userRepository.findAll(query);

I thought I could mock it with @Mock from Mockito as follows, but it seems that the instance of Specification (the argument query of findAll) cannot be the same instance that is specified when it is actually called, resulting in findAll being called with different arguments.

UserSpecification spec = new UserSpecification();
Specification<User> query = Specification.where(spec.userIdEqual("1"))
                    .and(spec.nameContains("john")
                    .and(spec.startDateGreaterThanEqual("2024-1-1"))
                    .and(spec.endDateLessThanEqual("2024-1-2"))

when(userRepository.findAll(query)).thenReturn(userList)

How should I mock in cases where Specification is used like this? If anyone knows, I would appreciate your guidance.

4
  • This is not clearly showing your use case. Can you provide your test and also your test configuration? Best would be to add a stackoverflow.com/help/minimal-reproducible-example
    – kSp
    Commented May 18 at 7:03
  • My recommendation is to use an embedded database as H2 and run your services against a database instead of spending time on mocking repositories. Your tests will have a higher degree of confidence and will be clearer as well. An embedded database is very fast as well. I find that mocking repositories just obscures the tests but it is just a suggestion.
    – silver_mx
    Commented May 18 at 22:30
  • Thank you for your suggestion. In this Service layer, an instance of Specification<User> is passed to "userRepository.findAll" to retrieve data. Therefore, as a test for the Service layer, I want to verify that an instance of Specification<User> is correctly created. Of course, I will also implement repository tests using H2, but I intend to test whether UserSpecification is implemented correctly as repository tests.
    – harunaga
    Commented May 19 at 9:31
  • Hence, for the Service layer test, I wanted to check if the correct instance of Specification<User> is created and if findAll is called by using something like when(userRepository.findAll(query)).thenReturn(userList). Is there a way to do that?
    – harunaga
    Commented May 19 at 9:31

1 Answer 1

1
when(userRepository.findAll(Mockito.any(Specification.class))).thenReturn(userList);
1
  • Thank you for your answer! This indeed seems to work, but I think it will return userList for any instance of Specification. If I also want to check whether the Specification instance query meets the following conditions, is there a good way to do that?? Specification.where(spec.userIdEqual("1")) .and(spec.nameContains("john")) .and(spec.startDateGreaterThanEqual("2024-1-1")) .and(spec.endDateLessThanEqual("2024-1-2"))
    – harunaga
    Commented May 19 at 9:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.