0

By using JMockit @Capturing, it was unable to capture call to any spring data jpa repository methods.

public interface UserRepository extends JpaRepository<UserEntity, Long> {

    UserEntity findByName(String name);
}

public class DefaultUserService implements UserService {

    public User getUser(Long id) {
        return userRepo.findOne( id );
    }

    public User getUser(String name) {
        return userRepo.findByName( name );
    }
}

public class UserServiceTest extends AbstractServiceTest {

    @Inject UserService userService;
    **@Capturing UserRepository userRepo;**

    @Test
    public void getUser_ShouldReturnUserObject() {
        **new Expectations() {{
            userRepo.findByName(anyString);
            result = new UserEntity(1l, null, null, null, null);
        }};**

        User user = userService.getUser("abc");

        assertNotNull(user.getId());
        assertEquals(1l, user.getId().longValue());
    }
}

However by replacing

UserRepository

with

JpaRepository<UserEntity, Long>

in the test class, JMockit able to intercept call to any methods available in JpaRepository interface like findOne() or findAll().

But it just not able to capture calls to custom repository methods that extends JpaRepository such as findByName().

I prefer to use @Capturing for this scenario even though JMockit state-based testing such as MockUp and Deencapsulation can solve this issue because it is much more simpler.

Any one has any ideas to solve this issue?

kenn3th
  • 1,187
  • 2
  • 22
  • 47

1 Answers1

0

Without knowing what AbstractServiceTest + Spring is doing with respect to the @Inject fields, I can't tell why @Capturing fails. Maybe Spring creates a proxy object which delegates to another, but even then...

Anyway, unit tests like these can be more easily written:

public class UserServiceTest
{
    @Tested DefaultUserService userService;
    @Injectable UserRepository userRepo;

    @Test
    public void getUser_ShouldReturnUserObject()
    {
        new Expectations() {{
            userRepo.findByName(anyString);
            result = new User(1l, null, null, null, null);
        }};

        User user = userService.getUser("abc");

        assertNotNull(user.getId());
        assertEquals(1l, user.getId().longValue());
    }
}

Unless you want to perform integration testing, it's generally best to let the mocking tool (JMockit in this case) do the injection of mock objects into tested objects.

Rogério
  • 16,171
  • 2
  • 50
  • 63