【问题标题】:Couldn't call JpaRepository in test unit无法在测试单元中调用 JpaRepository
【发布时间】:2021-08-30 20:32:49
【问题描述】:

我要测试一个serviceImpl(UpdateServiceImpl),测试是这样的:

@SpringBootTest
public class UpdateUserServiceImplTests {

    @Spy
    UserRepository userRepository;

    @Mock
    private UserInfoUpdate userInfoUpdate;

    @Autowired
    UserRepository userRepository1;

    @Spy
    @InjectMocks
    private UpdateUserServiceImpl updateUserServiceImpl;

    @BeforeEach
    public void setupMock() {
        MockitoAnnotations.openMocks(this);
        userInfoUpdate = new UserInfoUpdate();
    }

    @Test
    public void makeUserInfoRight (){

            try {
                System.out.println(userInfoUpdate.getUsername());
                User user = updateUserServiceImpl.makeUserInfoFull(userInfoUpdate);
                User user_to_update = userRepository1.findById(userInfoUpdate.getUsername())
                        .orElseThrow(() 
                        -> new UserNotFoundException("User not found by thisusername : " + "{" +
                         userInfoUpdate.getUsername() + "}"));
}

要测试的updateUserServiceImpl中的方法(makeUserInfoFull())是这样的:

@Service
public class UpdateUserServiceImpl implements UpdateUserService {

    @Autowired
    UserRepository userRepository;

    @Autowired
    InfoGuess infoGuess;

    @Override
    public User makeUserInfoFull(UserInfoUpdate userInfoUpdate)
            throws UserNotFoundException {

        User user_to_update =
                userRepository.findById(userInfoUpdate.getUsername())
                        .orElseThrow(() -> new UserNotFoundException("User not found by this username : " + "{" + userInfoUpdate.getUsername() + "}"));

存储库很简单:

@Service
public interface UserRepository extends JpaRepository<User, String> {
}

JpaRepository 接口通过 @Autowired 在测试单元中正常工作(生成 userRepository1),但是方法中的接口( makeUserInfoFull() )我尝试使用@Spy 模拟到测试中,即存储库(例如:userRepository.findAll() ) 保持返回空结果。 是不是没有办法通过JpaRepositoy在测试中使用真实数据?

【问题讨论】:

    标签: java jpa testing methods entity


    【解决方案1】:

    您还必须按照以下方式模拟该存储库。

    @Mock
    UserRepository userRepository1;
    

    然后它将被注入到该服务类中。

    然后你可以在调用时使用 mockito 并返回你想要的。 Mockito.when(userRepository1.findById(anyString()).thenReturn(object)

    【讨论】:

    • 测试中使用的userRepository1(通过@Autowired)工作正常。我想测试的Impl(UpdateUserServiceImpl)使用接口存储库(userRepository),我使用@Spy来,预计它可以在UpdateUserServiceImpl中运行但它没有。
    【解决方案2】:

    我认为在单元测试中使用真实数据并不好,因为:

    1. 数据库会弄脏测试数据(包含正负大小写)
    2. 如果我们必须更新代码以避免数据为空或已经存在,这没有任何意义。
    3. 与2号相关,单元测试应该是独立的。不依赖于其他测试甚至数据库。

    在我看来,我们有两种选择:

    1. 使用 Mockito 模拟其他服务,例如数据库甚至 3rd 方集成。为了使我们的单元测试比使用@SpringBootTest 更独立,也更快
    2. 如果我们真的必须使用数据库集成,您可以只使用 H2 数据库进行单元测试。所以在实际环境中你使用的是 Mysql 或其他任何东西,并且仅使用 H2 数据库进行单元测试

    【讨论】:

      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-26
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      相关资源
      最近更新 更多