Mockito 在本地模拟最后一堂课,但在 Jenkins 中失败

Chr*_*tos 13 java testng unit-testing mockito

我为静态方法编写了一些单元测试。静态方法只接受一个参数。参数的类型是 final 类。在代码方面:

public class Utility {

   public static Optional<String> getName(Customer customer) {
       // method's body.
   }
}

public final class Customer {
   // class definition
}
Run Code Online (Sandbox Code Playgroud)

因此,对于Utility该类,我创建了一个测试类,UtilityTests在该类中我为此方法编写了测试getName。单元测试框架是TestNG,使用的模拟库是Mockito. 所以一个典型的测试具有以下结构:

public class UtilityTests {

   @Test
   public void getNameTest() {
     // Arrange
     Customer customerMock = Mockito.mock(Customer.class);
     Mockito.when(...).thenReturn(...);

     // Act
     Optional<String> name = Utility.getName(customerMock);

     // Assert
     Assert.assertTrue(...);
   }
}
Run Code Online (Sandbox Code Playgroud)

问题是什么 ?

虽然测试在本地成功运行,但在 IntelliJ 中,它们在 Jenkins 上失败(当我将代码推送到远程分支时,会触发构建并在最后运行单元测试)。错误消息类似于以下内容:

org.mockito.exceptions.base.MockitoException: 不能模拟/监视类 com.packagename.Customer Mockito 不能模拟/监视,因为: - 最终类

我试过什么?

我搜索了一下,以找到解决方案,但我没有成功。我在此注意,我不能改变Customer最后一堂课的事实。除此之外,我希望如果可能的话,根本不改变它的设计(例如,创建一个接口,它将保存我想要模拟的方法并声明 Customer 类实现了该接口,正如 Jose 在他的评论)。我尝试的是mockito-final 中提到的第二个选项。尽管这解决了问题,但它阻止了其他一些单元测试:(,无法以不明显的方式修复。

问题

所以这是我的两个问题:

  1. 这怎么可能呢?测试不应该在本地和 Jenkins 中都失败吗?
  2. 如何根据我上面提到的约束来解决这个问题?

在此先感谢您的帮助。

Joh*_*pha 1

另一种方法是使用“方法到类”模式。

  1. 将方法从客户类移到另一个或多个类中,例如 CustomerSomething 例如/CustomerFinances (或任何它的责任)。
  2. 向 Customer 添加一个构造函数。
  3. 现在您不需要模拟 Customer,只需模拟 CustomerSomething 类即可!如果它没有外部依赖项,您可能也不需要模拟它。

这是关于该主题的一个很好的博客:https ://simpleprogrammer.com/back-to-basics-mock-elimination-patterns/