Spring Boot中Mockito的@InjectMocks与@Mock使用问题求助
问题描述
测试CompanyService时遇到异常:从SQL文件加载用户执行测试会报错,但将相关服务标记为@Mock时测试正常通过,而我必须使用@InjectMocks注入该服务。相关测试代码和addCompany方法如下:
测试代码
public class CompanyServiceUnitTest { @InjectMocks private CompanyService companyService; @Mock private UserCompanyService userCompanyService; @Mock private CompanyRepository companyRepository; @Test public void checkUserCompanyServiceNotCalled_WhenuserListEmpty() throws BadRequestException, ResourceNotFoundException { User user2 = new User(); user2.setId(3); List<User> listUsers = new ArrayList<>(); CompanyForm companyForm = new CompanyForm(); companyForm.setName("ekeepit"); companyForm.setCity("Lille"); companyForm.setContact("Ekeep"); companyForm.setEmail("ekeepit@ekeepit.com"); companyForm.setPhone("0303034343"); companyForm.setUsers(listUsers); Company company1 = companyService.addCompany(companyForm, user2); verifyNoInteractions(userCompanyService); } }
addCompany方法实现
public Company addCompany(final CompanyForm companyForm, final User organisationOwner) throws ResourceNotFoundException, BadRequestException { if (companyForm == null || organisationOwner == null) { log.error("CompanyForm and OrganisationOwner can not be null"); throw new BadRequestException("CompanyForm and OrganisationOwner can not be null"); } else if (StringUtils.isEmpty(companyForm.getName()) || StringUtils.isEmpty(companyForm.getContact()) || StringUtils.isEmpty(companyForm.getEmail()) || StringUtils.isEmpty(companyForm.getPhone()) || StringUtils.isEmpty(companyForm.getCity())) { log.error("All fields must be filled."); throw new BadRequestException("All fields must be filled."); } else if (!pattern.matcher(companyForm.getEmail()).matches()) { log.error("Email format is not valid."); throw new BadRequestException("Email format is not valid."); } Company company = Company.builder().createdAt(LocalDateTime.now()) .organization(this.organizationRepository.findOrganizationByOwner(organisationOwner) .orElseThrow(() -> new ResourceNotFoundException( "No organisation for the user " + organisationOwner.getId()))) .name(companyForm.getName()).disable(false).city(companyForm.getCity()) .contact(companyForm.getContact()).email(companyForm.getEmail()).phone(companyForm.getPhone()).build(); companyRepository.save(company); if (Objects.nonNull(companyForm.getUsers())) { List<UserCompany> userCompanies = companyForm.getUsers().stream().map(user -> { UserCompany userCompany = new UserCompany(); userCompany.setUser(user); userCompany.setCompany(company); userCompany.setDisable(false); return userCompany; }).collect(Collectors.toList()); this.userCompanyService.add(userCompanies); } return company; }
解决方案
- 补充缺失的Mock依赖:你的测试只Mock了
UserCompanyService和CompanyRepository,但addCompany方法中调用了未被Mock的organizationRepository.findOrganizationByOwner(),当使用SQL文件中的真实用户时,该方法会执行真实查询,找不到对应Organization就抛出ResourceNotFoundException。在测试类中添加OrganizationRepository的Mock并指定返回值:@Mock private OrganizationRepository organizationRepository; @Test public void checkUserCompanyServiceNotCalled_WhenuserListEmpty() throws BadRequestException, ResourceNotFoundException { User user2 = new User(); user2.setId(3); List<User> listUsers = new ArrayList<>(); // Mock organizationRepository的返回结果,避免抛出异常 Organization mockOrganization = new Organization(); when(organizationRepository.findOrganizationByOwner(user2)) .thenReturn(Optional.of(mockOrganization)); CompanyForm companyForm = new CompanyForm(); companyForm.setName("ekeepit"); companyForm.setCity("Lille"); companyForm.setContact("Ekeep"); companyForm.setEmail("ekeepit@ekeepit.com"); companyForm.setPhone("0303034343"); companyForm.setUsers(listUsers); Company company1 = companyService.addCompany(companyForm, user2); verifyNoInteractions(userCompanyService); } - 匹配SQL数据与Mock逻辑:如果必须使用SQL文件中的真实用户,需确保SQL文件中包含该用户对应的Organization数据,或者根据SQL加载的用户ID调整Mock的返回值。
- 验证断言逻辑:
companyForm.getUsers()为空列表时,userCompanyService.add()不会被执行,verifyNoInteractions(userCompanyService)的断言逻辑正确,补充Mock后测试即可正常通过。
内容的提问来源于stack exchange,提问作者user13906062
相关产品推荐
相关产品推荐

