mockito - Long 和 Lombok 的 Mockito 问题
问题描述
如何为以下代码编写 mockito,我经历了:https ://examples.javacodegeeks.com/core-java/junit/junit-mockito-when-thenreturn-example/
代码:
@Override
public void saveEmployee(EmployeeDto dto) {
Department department = getByDepartmentId(dto.getDepartmentId());
RoleType roleType = getByRoleTypeId(dto.getRoleTypeId());
Employee departmentMember = convertToEntity(dto, department, roleType);
try {
departmentMemberRepository.save(departmentMember);
} catch (DataIntegrityViolationException e) {
throw new PCDataIntegrityViolationException("error");
} catch (Exception ex) {
throw new InternalServerException(HttpStatus.INTERNAL_SERVER_ERROR, "error", ex);
}
}
private Employee convertToEntity(EmployeeDto dto, Department department, RoleType roleType) {
return Employee.pmBuilder()
.memberEmployeeId(dto.getMemberEmployeeId())
.memberEmployeeName(dto.getMemberEmployeeName())
.createUser(dto.getCreateUser())
.lastUpdateUser(dto.getLastUpdateUser())
.status(StatusEnum.get(dto.getStatus()))
.department(department)
.roleType(roleType)
.build();
}
private Department getByDepartmentId(Long departmentId) {
Optional<Department> optDepartment = departmentRepository.findById(departmentId);
if(!optDepartment.isPresent()) {
throw new ResourceNotFoundException("Error");
}
return optDepartment.get();
}
private RoleType getByRoleTypeId(Integer roleTypeId) {
RoleType roleType = roleTypeRepository.findByRoleTypeId(roleTypeId);
if(roleType == null) {
throw new ResourceNotFoundException("error");
}
return roleType;
}
我已经写了测试课,唯一的问题是
@RunWith(PowerMockRunner.class)
@PrepareForTest({AHUtils.class })
public class EmployeeServiceTest {
@InjectMocks
private EmployeeServiceimpl employeeServiceimpl;
@Mock
private Pageable pageable;
@Mock
private Page<Employee> employeePage;
@Mock
private EmployeeRepository employeeRepository;
@Mock
private DepartmentRepository departmentRepositoryMock;
@Mock
private Employee employee;
@Mock
private Optional<Employee> employeeOptional;
@Mock
private Department departmentMock;
@Mock
private Optional<Department> departmentOptionalMock;
@Mock
private EmployeeDto employeeDto;
@Mock
private Sort sortMock;
@Mock
private Exception ex;
@Mock
private Environment env;
@Test(expected = ResourceNotFoundException.class)
public void test_RoleTypeNotPresent() {
when(departmentOptionalMock.get()).thenReturn(departmentMock);
when(departmentOptionalMock.isPresent()).thenReturn(true);
when(departmentRepositoryMock.findById(null)).thenReturn(departmentOptionalMock);
doThrow(new ResourceNotFoundException("error")).when(employeeRepository).save(any());
when(employeeDto.getDepartmentId()).thenReturn(null);
employeeServiceimpl.saveEmployee(employeeDto);
}
}
什么时候Optional<Department> optDepartment = departmentRepository.findById(departmentId);
,我想在其中有价值,以便我继续,这个测试用例进入 if 块。
解决方案
如果您DepartmentRepository
没有被注入到您的体内,请EmployeeServiceimpl
确保以下事项(基于javadoc of InjectMocks
):
如果您至少有一个带参数的构造函数:(
在这种情况下,Mockito 使用构造函数注入)
所有应该注入的模拟必须是具有最多参数的构造函数的参数。
另请注意,如果存在非无参数构造函数,则 mockito 不会考虑其他注入方法。第二种情况是你有你想要模拟的东西的 setter 方法
(在这种情况下,Mockito 将使用 setter 注入)如果您只有一个无参数构造函数而没有设置器:(
在这种情况下,Mockito 将使用字段注入)
所有带有注释的模拟必须与您的类@Mock
中的字段共享相同的名称。EmployeeServiceimpl
Overmocking
通常是指您生成了太多模拟的事实,即使对于不需要模拟的东西也是如此。
您可以将前 3 行更改为以下示例所示的内容。
请注意,我.findById(null)
将.findById(anyLong())
. 我不确定getDepartmentId()
实际返回的是什么,对于一个原始的 long 你必须anyLong()
用作模拟将默认返回 0 (而不是 null )。
但是,在下面的示例中,我将其设置为departmentId
,1L
因此无论如何它都应该匹配。
@RunWith(PowerMockRunner.class)
@PrepareForTest({AHUtils.class })
public class EmployeeServiceTest {
@InjectMocks
private EmployeeServiceimpl employeeServiceimpl;
@Mock
private DepartmentRepository departmentRepositoryMock;
@Test(expected = ResourceNotFoundException.class)
public void test_RoleTypeNotPresent() {
Department department = new Department();
department.setDepartmentId(1L);
// only if you can't simply create that object, use the mock
// Department department = Mockito.mock(Department.class);
when(departmentRepositoryMock.findById(anyLong())).thenReturn(Optional.of(department));
// ... the rest of the example does not match with the code you posted ...
employeeServiceimpl.saveEmployee(employeeDto);
}
}
请注意,测试的剩余部分,
doThrow(new ResourceNotFoundException("error")).when(employeeRepository).save(any());
when(employeeDto.getDepartmentId()).thenReturn(null);
与您发布的代码并不真正匹配。相反,您应该在roleTypeRepository
.
我也不确定应该在什么时候抛出异常,因为似乎没有与employeeRepository
.
推荐阅读
- python - 在张量流中使用梯度 API
- javascript - 在 Vue CLI PWA 中缓存 API 或存储数据
- mysql - 从多个表中接收数据 [Nodejs,MySQL]
- xamarin - $(AndroidSupportedAbis) 中的值“armeabi”无效。不再支持此 ABI。Xamarin.Forms - VS2019
- wordpress - 完成迁移过程后,我应该何时从旧主机中删除数据?
- java - 改造调用包含错误必需的改造2.调用,发现无效
- processing - 小行星游戏 - 越野车碰撞检测
- php - VSCode - 格式 - 打开标签(php)作为代码最左边的标尺直到结束标签?
- python - python - 如何以保持相互索引一致的方式对dict和list进行排序?
- amazon-web-services - 使用 DeepAR 对多个独立产品进行时间序列预测