繁体   English   中英

Mockito 不嘲笑模拟对象的字段

[英]Mockito not mocking field of mocked object

我有一个如下所示的服务类:

public class MyServiceClassImpl implements MyServiceClass {

  private final MyRepository myRepository;

  private final EntityDTOConverter entityConverter;

...
}

其中 EntityDTOConverter 是一个 bean,用于将实体转换为 DTO,反之亦然。 它使用这样的 ModelMapper:

@Component
@RequiredArgsConstructor
public class EntityDTOConverter {

  private final ModelMapper modelMapper = new ModelMapper();
...
}

然后我试图像这样测试服务:

@ExtendWith(MockitoExtension.class)
class MyServiceClassImplTest {

  @InjectMocks
  private MyServiceClassImpl myServiceClass;

  @Mock
  private MyRepository myRepository;

  @Mock
  private EntityDTOConverter entityConverter;

  private Entity myEntity;

  private EntityDTO myEntityDTO;

  @BeforeEach
  public void setUp() {
    myEntityDTO = new EntityDTO();

    myEntity = Entity.newInstance("name", "surname", "email@email.com");
    myEntity.setId(randomUUID());

    lenient().when(myRepository.save(myEntity)).thenReturn(myEntity);
    lenient().when(entityConverter.convert(any(EntityDTO.class))).thenReturn(myEntity);
  }

基本上,我试图设置任何通过转换器的 DTO 都应该正确转换。 但这就是我得到的错误。 当它尝试模拟 entityConverter.convert() 方法时,它实际上是在调用该方法。 然后该方法使用 modelMapper,在这个模拟中它是null modelMapper 直接在类中初始化,如上面发布的(尽管我也尝试在应用程序上下文中将其设置为 bean 并注入它,但结果是相同的):

空模型映射器

这会在运行测试时产生 NPE。 我该如何解决?

Mockito 不能违反 Java 的规则。 这包括它不能更改特定代码行的执行顺序。 因此线

   lenient().when(entityConverter.convert(any(EntityDTO.class))).thenReturn(myEntity);

必须首先在真正的EntityDTOConverter类中执行convert()方法。 由于EntityDTOConverter类的当前实例是由Mockito创建的模拟,因此其字段初始化为null 因此,如果方法convert()访问这样的属性,则会引发 NPE。

这个问题的解决方案是使用另一种形式来配置mock:

doReturn(myEntity)
   .when(entityConverter).convert(any(EntityDTO.class))
// take care for the different positions of closing braces!

这样模拟(它基本上是你的真实类的扩展)拦截对convert()的调用,这样你在这个方法中的真实代码就不会被执行,也不会抛出 NPE。

如果mockito 实际上是在模拟convert方法,它就不会尝试访问modelMapper。 您可以尝试删除插入类的确切要求(例如entityConverter.convert(any()) )。

旁注 - 我不认为过度使用lenient是一个好习惯,所以除非真的有必要,否则你可能想放弃它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM