【问题标题】:More Mockito RETURNS_DEEP_STUBS woes更多 Mockito RETURNS_DEEP_STUBS 问题
【发布时间】:2017-10-23 22:31:51
【问题描述】:

我最近阅读并使用了下面链接的 GitHub 存储库中的一些示例,这些示例用于扩展基本的 Spring Boot 错误对象。我正在尝试为ApiError.java 类编写一些测试,特别是#addValidationErrors

https://github.com/brunocleite/spring-boot-exception-handling/blob/master/src/main/java/com/example/springbootexceptionhandling/ApiError.java

基本问题是我还没有找到一种方法来链接方法以返回值以工作。我此时的测试看起来像这样......

@Test
public void addValidationErrors() {
    ApiError apiError = new ApiError(HttpStatus.OK);
    ConstraintViolation mockViolation = Mockito.mock(ConstraintViolation.class, Mockito.RETURNS_DEEP_STUBS);
    Mockito.when(mockViolation.getRootBeanClass().getSimpleName()).thenReturn("MyBeanName");
...

此时测试在调用Mockito.when 方法的行上以NullPointerException 结束。我尝试了不同的运行器类(Mockito、JUnit4 甚至 PowerMock)以及各种注释组合,例如 @PrepareForTest,并在 @Mock 下在测试之外声明 mockViolation。

【问题讨论】:

    标签: java spring unit-testing testing mockito


    【解决方案1】:

    您的语法是正确的,但您的具体问题是 getRootBeanClass 返回 Class,而 Mockito 无法模拟最终类。在后台,当您要求模拟一个类时,Mockito 会生成一个子类,该子类(有效地)覆盖所有方法并将它们重定向到 Mockito 控件。这种覆盖机制是您在模拟 final 方法以及 final 类(如 java.lang.Class)时遇到问题的原因。

    尽管您可以使用 PowerMock 完成此操作,但不建议这样做,例如 2011 年的 Johan Haleby's post from powermock@googlegroups.com

    我认为模拟 Class 是不可能的,因为这会弄乱很多 PowerMock 内部的东西。如果您设置 MockGateway.MOCK_GET_CLASS_METHOD = true,您可以模拟对象的“getClass()”方法。

    我强烈建议 [原文如此] 反对模拟 Class 或 getClass 方法。尝试以其他方式验证它。

    因为您只关心使getSimpleName 返回一个可预测的值,请考虑创建一个新类(“MyBean”)并设置getRootBeanClass() 以返回它。在接口上模拟返回值将非常容易,并且您将获得与您希望使用的相同类型的简单名称返回值。

    【讨论】:

      猜你喜欢
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多