You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:05:17