我尝试在Sping Boot 中使用规范而不是使用findAllByAnything。当我尝试使用Specification for JUnit实现一个测试方法时,我得到了如下所示的错误。
我该如何解决问题?
下面getAdminUsersWithAdmin中显示的这部分返回null
Page<AdminUserEntity> adminUserEntitiesByOrganization = adminUserRepository.findAll(specification, listRequest.toPageable());
下面是名为getAdminUsersWithAdmin的相关方法
private Page<AdminUser> getAdminUsersWithAdmin(AdminUserListRequest listRequest) {
String organizationId = identity.getOrganizationId();
Specification<AdminUserEntity> specification = Specification
.where(AdminUserSpecifications.hasOrganizationId(organizationId));
Page<AdminUserEntity> adminUserEntitiesByOrganization = adminUserRepository.findAll(specification, listRequest.toPageable());
List<AdminUser> adminUsersByOrganization = adminEntityToAdminMapper.map(adminUserEntitiesByOrganization.getContent());
return Page.of(adminUserEntitiesByOrganization, adminUsersByOrganization);
}
下面是AdminUserSpecifications
public class AdminUserSpecifications {
public static Specification<AdminUserEntity> hasOrganizationId(String organizationId) {
return (root, query, criteriaBuilder) ->
SearchSpecificationBuilder.eq(criteriaBuilder, root.get("organizationId"), organizationId);
}
}
下面是SearchSpecificationBuilder中的eq方法
public static Predicate eq(CriteriaBuilder criteriaBuilder, Path<Object> path, Object value) {
if (value == null) {
return null;
}
return criteriaBuilder.equal(path, value);
}
下面是测试方法
@Test
void givenUserListRequest_whenAdminwithRoleIsAdmin_thenReturnAllAdminUsers() {
// Given
AdminUserListRequest mockAdminUserListRequest = new AdminUserListRequestBuilder().withValidValues().build();
AdminUserEntity mockAdminUserEntity = new AdminUserEntityBuilder().withValidFields().build();
List<AdminUserEntity> mockAdminUserEntities = Collections.singletonList(mockAdminUserEntity);
Page<AdminUserEntity> mockPageAdminUserEntities = new PageImpl<>(mockAdminUserEntities);
List<AdminUser> mockAdminUsers = ADMIN_ENTITY_TO_ADMIN_MAPPER.map(mockAdminUserEntities);
Page<AdminUser> mockPageAdminUsers = Page.of(mockPageAdminUserEntities, mockAdminUsers);
UserType userType = UserType.ADMIN;
Specification<AdminUserEntity> specification = Specification.where(AdminUserSpecifications.hasOrganizationId(mockAdminUserEntity.getOrganizationId()));
// When
Mockito.when(identity.getUserType()).thenReturn(userType);
Mockito.when(identity.getOrganizationId()).thenReturn(mockAdminUserEntity.getOrganizationId());
Mockito.when(adminUserRepository.findAll(specification, mockAdminUserListRequest.toPageable()))
.thenReturn(mockPageAdminUserEntities);
Page<AdminUser> pageAdminUsers = adminUserService.getAdminUsers(mockAdminUserListRequest);
// Then
PageBuilder.assertEquals(mockPageAdminUsers, pageAdminUsers);
Mockito.verify(adminUserRepository, Mockito.times(1))
.findAll(specification, mockAdminUserListRequest.toPageable());
}
下面是运行givenUserListRequest_whenAdminwithRoleIsAdmin_thenReturnAllAdminUsers方法时显示的错误。
java.lang.NullPointerException: Cannot invoke "org.springframework.data.domain.Page.getContent()" because "adminUserEntitiesByOrganization" is null
编辑
我修改了如下所示的这一行
Mockito.when(adminUserRepository.findAll(Mockito.any(Specification.class), Mockito.eq(mockAdminUserListRequest.toPageable()))) .thenReturn(mockPageAdminUserEntities);
我得到这个问题如下所示
Argument(s) are different! Wanted:
adminUserRepository.findAll(
com.admin_user.repository.specification.AdminUserSpecifications$$Lambda$421/0x000000080121b220@7f02251,
Page request [number: 0, size 10, sort: UNSORTED]
);
adminUserRepository.findAll(
com.admin_user.repository.specification.AdminUserSpecifications$$Lambda$421/0x000000080121b220@dffa30b,
Page request [number: 0, size 10, sort: UNSORTED]
);
1条答案
按热度按时间u91tlkcl1#
问题就出在这一行:
你的规范是一个lambda -
Specification.where
返回传入的规范,如果它不为空,你传入一个由hasOrganizationId
创建的lambda。由于在Mockito.when中传递的参数和实际的prod代码不相等,Mockito返回默认值
Page<AdminUserEntity> adminUserEntitiesByOrganization
-对于任何非原始类型都是null。参见以下测试:
有两种解决方案:
选项1:放松对论证的期望
使用
Mockito.any(Specification.class)
Mockito.eq
)选项2:使用一个实现了equals(和hashCode以确保完整性)的对象
lambda可以修改为Specification的具体子类
在这两个选项中,我假设
mockAdminUserListRequest.toPageable()
返回的对象正确地实现了equals。如果不是,则添加等于或使用选项1或选项2。