有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javaspringbootmockito@injectmock说明如何仅模拟选定的依赖项

我有一个名为@ServiceUserServiceImpl依赖于另外两个bean。一个是UserRepositorybean,另一个是名为SessionService的bean

我的要求是在测试UserServiceImpl类期间,我必须能够注入SessionService依赖项的模拟,但保持UserRepository依赖项的原样

我的服务类如下所示:

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private SessionService sessionService;
    
    
    @Override
    public User create(User user) {
        log.info("User Creation at Service");
        // ... Do some validations .. //

        // This needs to be mocked in Unit Tests
        String returnValue = sessionService.doSomethingThatIDontWantInTests(); 

        user.setInternalKey(returnValue);

        // .. Do some more Validations .. //

        return userRepository.save(user);
    }
}

现在,这是我的测试课:

@SpringBootTest
class UserServiceTest {
    
    @InjectMocks
    private UserServiceImpl userService;
    
    @Mock
    private SessionService sessionService;
    
    
    @Test
    void CreateUserTest() {
        Mockito.when(sessionService.doSomethingThatIDontWantInTests()).thenReturn("abcxyz123321");
        User user = new User();
        user.setName("John Doe");
        user.setEmail("john.doe@example.com");
        User savedUser = userService.create(user);
        
        assertNotNull(savedUser.getUserId());

    }
}

当我运行这个测试时,Mockito成功地模拟了SessionService调用。但是,UserServiceImpl.createUser()仍然失败,消息说:

java.lang.NullPointerException: Cannot invoke "com.myproject.data.repos.UserRepository.save(User)" because "this.userRepository" is null

我是否应该将UserRepository也作为mock注入,并使用Mockito来模拟UserRepository.save()方法

我只想模拟SessionService依赖项,而不是UserRepository依赖项

这是可行的吗?如果是,怎么做?请告知

谢谢, 斯利拉姆


共 (2) 个答案

  1. # 2 楼答案

    你正在混合不同的测试风格

    Style 1-spring集成测试

    此时,Spring Boot在其上下文中创建bean,并将它们注入测试类

    • 使用@SpringBootTest
    • 使用@Autowired将bean注入测试
    • 使用@MockBean将Spring上下文中的bean替换为mock

    风格2-单元测试

    这不使用Spring DI。在这种风格中,模拟所有依赖项是典型的

    • 使用@ExtendWith(MockitoExtension.class)
    • 将依赖项注释为@Mock
    • @InjectMocks注释SUT

    使用真正的依赖关系也是可能的,但在这种情况下,您需要手动构造SUT-Mockito不支持部分注入

    单元测试往往更加轻量级,不那么脆弱,另一方面,集成测试覆盖了应用程序的很大一部分

    请注意,如果UserRepository是spring数据repo,则不能手动创建它