【问题标题】:Why this mockito does not mock为什么这个模仿者不模仿
【发布时间】:2017-03-21 01:51:11
【问题描述】:

这是测试类:

@MockBean
private UserRepository userRepository;

@Before
public void beforeClass() {
    String mobile;
    when(this.userRepository.findByMobile(Mockito.anyString())).thenAnswer(new Answer<User>() {
        @Override
        public User answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            return MockData.getUserByMobile((String) args[0]);
        }
    });
}

@Test
@WithUserDetails(value = MockData.CUSTOMER_USERNAME, userDetailsServiceBeanName = "customizedUserDetailsService")
public void testAdd() throws Exception {}

这是userDetails 的实现:

@Autowired
private UserRepository userRepository;

@Override
@Transactional
public UserDetails loadUserByUsername(String username) {
    User user = (User) userRepository.findByMobile(username); // user is always null 

我期望的是当userRepository.findByMobile被调用时,它应该调用@Before中定义的getUserByMobile方法。但显然Mockito 配置不起作用或userRepository 无法模拟。出了什么问题以及如何解决?

【问题讨论】:

    标签: spring-mvc mockito


    【解决方案1】:

    UserRepository 用于 userDetails 实现,需要注入到 userDetails 中,如this 所述。但是因为 XXRepository 在接口中,所以不能使用@InjectedMock。然后类变成: 测试类:

        @MockBean
        private UserService userService;
    
        @InjectMocks
        private CustomizedUserDetailsService customizedUserDetailsService;
    
        @Before
        public void before() {
            MockitoAnnotations.initMocks(this);
            when(this.userService.findByMobile(Mockito.anyString())).thenAnswer(new Answer<User>() {
                @Override
                public User answer(InvocationOnMock invocation) throws Throwable {
                    Object[] args = invocation.getArguments();
                    return MockData.getUserByMobile((String) args[0]);
                }
            });
        }
    
        @Test
        @WithUserDetails(value = MockData.CUSTOMER_USERNAME, userDetailsServiceBeanName = "customizedUserDetailsService") {}
    

    还有用户详细信息:

    @Autowired
    private UserService userService;
    
    @Override
    @Transactional
    public UserDetails loadUserByUsername(String username) {
        User user = (User) userService.findByMobile(username);
    

    我可以看到 userDetails 中的 userService 与测试类中模拟的 userService 相同,但是在 @WithUserDetails userDetails 之后调用了 @Before 方法。所以最后为了实现加载MockData用户,我想我必须为UT创建另一个userDetails。编辑 2:实际上,我在没有 @InjectMocks 并使用 userService 的情况下尝试过(最初我使用的是 userRepository),它也可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      相关资源
      最近更新 更多