【问题标题】:JMockit unable to capture spring data jpa repository callsJMockit 无法捕获 spring 数据 jpa 存储库调用
【发布时间】:2014-06-07 18:40:42
【问题描述】:

通过使用 JMockit @Capturing,它无法捕获对任何 spring data jpa 存储库方法的调用。

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());
    }
}

但是通过替换

用户存储库

JpaRepository&lt;UserEntity, Long&gt;

在测试类中,JMockit 能够拦截对 JpaRepository 接口中任何可用方法的调用,例如 findOne() 或 findAll()。

但它只是无法捕获对扩展 JpaRepository 的自定义存储库方法的调用,例如 findByName()。

我更喜欢在这种情况下使用 @Capturing,尽管基于 JMockit 状态的测试(例如 MockUp 和 Deencapsulation)可以解决这个问题,因为它更简单。

有人有解决这个问题的想法吗?

【问题讨论】:

    标签: java spring-data-jpa jmockit


    【解决方案1】:

    不知道AbstractServiceTest + Spring 对@Inject 字段做了什么,我不知道为什么@Capturing 会失败。也许 Spring 创建了一个代理对象,该代理对象委托给另一个对象,但即便如此......

    无论如何,像这样的 unit 测试可以更容易编写:

    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());
        }
    }
    

    除非您想执行集成测试,否则最好让模拟工具(在本例中为 JMockit)将模拟对象注入测试对象。

    【讨论】:

      猜你喜欢
      • 2018-09-21
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      • 2016-01-08
      • 2017-10-28
      相关资源
      最近更新 更多