Mockito - 你不能在验证或存根之外使用参数匹配器 - 已经尝试了很多东西但仍然没有解决方案
Mockito - You cannot use argument matchers outside of verification or stubbing - have tried many things but still no solution
我有如下一段代码:
PowerMockito.mockStatic(DateUtils.class);
//And this is the line which does the exception - notice it's a static function
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
class 开头为:
@RunWith(PowerMockRunner.class)
@PrepareForTest({CM9DateUtils.class,DateUtils.class})
我得到org.Mockito.exceptions.InvalidUseOfMatchersException......你不能在验证或存根之外使用参数匹配器.....(错误出现两次失败跟踪 - 但都指向同一行)
在我的代码的其他地方,when 的用法已完成并且工作正常。另外,在调试我的代码时,我发现 any(Date.class) returns null。
我尝试了以下解决方案,我看到其他人发现这些解决方案很有用,但对我来说不起作用:
正在添加
@After
public void checkMockito() {
Mockito.validateMockitoUsage();
}
或
@RunWith(MockitoJUnitRunner.class)
或
@RunWith(PowerMockRunner.class)
改为
PowerMockito.when(new Boolean(DateUtils.isEqualByDateTime(any(Date.class), any(Date.class)))).thenReturn(false);
使用anyObject()
(不编译)
正在使用
notNull(Date.class)
或(Date)notNull()
替换
when(........).thenReturn(false);
和
Boolean falseBool=new Boolean(false);
和
when(.......).thenReturn(falseBool);
如 PowerMockito Getting Started Page 中所述,您需要使用 PowerMock 运行器和 @PrepareForTest
注释。
@RunWith(PowerMockRunner.class)
@PrepareForTest(DateUtils.class)
确保您使用的是 JUnit 4 附带的 @RunWith 注释,org.junit.runner.RunWith
。因为它总是接受 value
属性,所以如果您使用正确的 RunWith 类型,您会收到该错误,这对我来说很奇怪。
any(Date.class)
对 return null
是正确的:Mockito 没有使用魔术 "matches any Date" 实例,而是使用 a hidden stack of matchers 来跟踪哪些匹配器表达式对应匹配的参数,returns null
对象(整数为 0,布尔值为 false,等等)。
所以最后,对我有用的是将执行异常的行导出到其他一些静态函数。我称之为 compareDates.
我的实现:
在被测试的class中(例如-MyClass)
static boolean compareDates(Date date1, Date date2) {
return DateUtils.isEqualByDateTime (date1, date2);
}
并在测试中 class:
PowerMockito.mockStatic(MyClass.class);
PowerMockito.when(MyClass.compareDates(any(Date.class), any(Date.class))).thenReturn(false);
不幸的是,我不能说我完全理解为什么这个解决方案有效而以前的没有。
也许这与 DateUtils class 不是我的代码有关,我无法访问它的源代码,只能访问生成的 .class 文件,但我真的不确定。
编辑
上述解决方案只是一种解决方法,并未解决在代码中覆盖 DateUtils
isEqualByDateTime 调用的需要。
实际上 解决了真正的问题是导入具有实际实现的 DateUtils
class 而不是只是扩展它的那个,这是我之前导入的.
这样做之后我可以使用原来的线路
PowerMockito.mockStatic(DateUtils.class);
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
无一例外。
我在 Kotlin 测试 Class
中遇到了与 TextUtils 类似的问题
PowerMockito.`when`(TextUtils.isEmpty(Mockito.anyString())).thenReturn(true)
通过在我的测试之上添加以下代码解决了这个问题Class
@PrepareForTest(TextUtils::class)
并在 PowerMockito 之前调用了 mockStatic。`when`
PowerMockito.mockStatic(TextUtils::class.java)
我有如下一段代码:
PowerMockito.mockStatic(DateUtils.class); //And this is the line which does the exception - notice it's a static function PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
class 开头为:
@RunWith(PowerMockRunner.class)
@PrepareForTest({CM9DateUtils.class,DateUtils.class})
我得到org.Mockito.exceptions.InvalidUseOfMatchersException......你不能在验证或存根之外使用参数匹配器.....(错误出现两次失败跟踪 - 但都指向同一行)
在我的代码的其他地方,when 的用法已完成并且工作正常。另外,在调试我的代码时,我发现 any(Date.class) returns null。
我尝试了以下解决方案,我看到其他人发现这些解决方案很有用,但对我来说不起作用:
正在添加
@After public void checkMockito() { Mockito.validateMockitoUsage(); }
或
@RunWith(MockitoJUnitRunner.class)
或
@RunWith(PowerMockRunner.class)
改为
PowerMockito.when(new Boolean(DateUtils.isEqualByDateTime(any(Date.class), any(Date.class)))).thenReturn(false);
使用
anyObject()
(不编译)正在使用
notNull(Date.class)
或(Date)notNull()
替换
when(........).thenReturn(false);
和
Boolean falseBool=new Boolean(false);
和
when(.......).thenReturn(falseBool);
如 PowerMockito Getting Started Page 中所述,您需要使用 PowerMock 运行器和 @PrepareForTest
注释。
@RunWith(PowerMockRunner.class)
@PrepareForTest(DateUtils.class)
确保您使用的是 JUnit 4 附带的 @RunWith 注释,org.junit.runner.RunWith
。因为它总是接受 value
属性,所以如果您使用正确的 RunWith 类型,您会收到该错误,这对我来说很奇怪。
any(Date.class)
对 return null
是正确的:Mockito 没有使用魔术 "matches any Date" 实例,而是使用 a hidden stack of matchers 来跟踪哪些匹配器表达式对应匹配的参数,returns null
对象(整数为 0,布尔值为 false,等等)。
所以最后,对我有用的是将执行异常的行导出到其他一些静态函数。我称之为 compareDates.
我的实现:
在被测试的class中(例如-MyClass)
static boolean compareDates(Date date1, Date date2) {
return DateUtils.isEqualByDateTime (date1, date2);
}
并在测试中 class:
PowerMockito.mockStatic(MyClass.class);
PowerMockito.when(MyClass.compareDates(any(Date.class), any(Date.class))).thenReturn(false);
不幸的是,我不能说我完全理解为什么这个解决方案有效而以前的没有。
也许这与 DateUtils class 不是我的代码有关,我无法访问它的源代码,只能访问生成的 .class 文件,但我真的不确定。
编辑
上述解决方案只是一种解决方法,并未解决在代码中覆盖 DateUtils
isEqualByDateTime 调用的需要。
实际上 解决了真正的问题是导入具有实际实现的 DateUtils
class 而不是只是扩展它的那个,这是我之前导入的.
这样做之后我可以使用原来的线路
PowerMockito.mockStatic(DateUtils.class);
PowerMockito.when(DateUtils.isEqualByDateTime (any(Date.class),any(Date.class)).thenReturn(false);
无一例外。
我在 Kotlin 测试 Class
中遇到了与 TextUtils 类似的问题PowerMockito.`when`(TextUtils.isEmpty(Mockito.anyString())).thenReturn(true)
通过在我的测试之上添加以下代码解决了这个问题Class
@PrepareForTest(TextUtils::class)
并在 PowerMockito 之前调用了 mockStatic。`when`
PowerMockito.mockStatic(TextUtils::class.java)