我最近阅读并使用了下面链接的 GitHub Repo 中的一些示例,这些示例用于扩展基本的 Spring Boot 错误对象。我正在尝试为 ApiError.java
类编写一些测试,特别是 #addValidationErrors
基本问题是我还没有找到一种方法来链接方法以返回值。我此时的测试看起来像这样......
@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。
最佳答案
您的语法是正确的,但您的具体问题是 getRootBeanClass
返回一个 Class
,而 Mockito 无法模拟最终类。在幕后,当您要求模拟一个类时,Mockito 会生成一个子类,该子类(有效地)覆盖所有方法并将它们重定向到 Mockito 控件。这种覆盖机制就是为什么您在模拟 final
方法以及 java.lang.Class
等 final
类时会遇到麻烦。
虽然您可以使用 PowerMock 完成此操作,但不建议这样做,如 Johan Haleby's post from powermock@googlegroups.com 中所示2011 年:
I don't think there's a possibility to mock Class because that will mess up a lot of PowerMock internal stuff. You can how ever mock the "getClass()" method of Objects if you set MockGateway.MOCK_GET_CLASS_METHOD = true.
I would strongly advice [sic] against mocking Class or getClass method though. Try to verify it in some other way.
因为您只关心使 getSimpleName
返回一个可预测的值,请考虑创建一个新类(“MyBean”)并设置 getRootBeanClass()
以返回它。在接口(interface)上模拟返回值将非常容易,并且您将获得与您希望使用的相同类型的简单名称返回值。
关于java - 更多 Mockito RETURNS_DEEP_STUBS 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46899506/