在 Java 单元测试中,如何验证函数类型的变量被调用时传入了某些参数?
In Java unit testing, how to verify a variable of type Function is called with certain arguments passed in?
我有一个 Function
类型的变量,例如:
Class SomeClass{
static final Function<Throwable, Optional<String>> SOME_FUNCTION = throwable -> Optional.empty();
}
我想知道如何验证它在特定时间被调用并在特定参数中被传递?
我需要的是以下代码的等价物:
verify(SomeClass, times(2)).SOME_FUNCTION(any(Exception.class));
提前致谢!
您需要将 SOME_FUNCTION
替换为可以断言调用的 Mockito 模拟。根据您的情况,可能有几种方法可以实现此目的:
作为成员传入函数
如果您需要对其执行断言的函数不一定需要是最终静态的,并且在您的情况下传递它是有意义的:
class MyClass {
final Function<Throwable, Optional<String>> someFunction;
public MyClass(Function<Throwable, Optional<String>> someFunction) {
this.someFunction = someFunction;
}
// ...
}
然后你可以在你的测试中传递一个模拟:
Function<Throwable, Optional<String>> mockFunc = Mockito.mock(Function.class);
var myClass = new MyClass(mockFunc);
// ... test code ...
verify(mockFunc, times(2)).apply(any(Exception.class));
如果函数需要保持静态,但您仍然可以创建变量 non-final,那么您只需通过静态赋值来更改它,它应该可以正常工作。在这种情况下,请记住之后将其设置回原始值。
使用反射模拟静态成员
如果您无法更改 class' 代码,并且 需要 对静态函数执行断言,它会变得有点棘手。您可以尝试使用反射将函数替换为模拟。 Mockito 有一个 Whitebox
class 封装了其中的一些:
Function<Throwable, Optional<String>> mockFunc = Mockito.mock(Function.class);
Whitebox.setInternalState(MyClass.class, "SOME_FUNCTION", mockFunc);
// ... test code ...
verify(mockFunc, times(2)).apply(any(Exception.class));
但这很可能会产生一些不必要的副作用(例如 SOME_FUNCTION
模拟时间比预期的长),并且只能作为最后的手段。
我有一个 Function
类型的变量,例如:
Class SomeClass{
static final Function<Throwable, Optional<String>> SOME_FUNCTION = throwable -> Optional.empty();
}
我想知道如何验证它在特定时间被调用并在特定参数中被传递?
我需要的是以下代码的等价物:
verify(SomeClass, times(2)).SOME_FUNCTION(any(Exception.class));
提前致谢!
您需要将 SOME_FUNCTION
替换为可以断言调用的 Mockito 模拟。根据您的情况,可能有几种方法可以实现此目的:
作为成员传入函数
如果您需要对其执行断言的函数不一定需要是最终静态的,并且在您的情况下传递它是有意义的:
class MyClass {
final Function<Throwable, Optional<String>> someFunction;
public MyClass(Function<Throwable, Optional<String>> someFunction) {
this.someFunction = someFunction;
}
// ...
}
然后你可以在你的测试中传递一个模拟:
Function<Throwable, Optional<String>> mockFunc = Mockito.mock(Function.class);
var myClass = new MyClass(mockFunc);
// ... test code ...
verify(mockFunc, times(2)).apply(any(Exception.class));
如果函数需要保持静态,但您仍然可以创建变量 non-final,那么您只需通过静态赋值来更改它,它应该可以正常工作。在这种情况下,请记住之后将其设置回原始值。
使用反射模拟静态成员
如果您无法更改 class' 代码,并且 需要 对静态函数执行断言,它会变得有点棘手。您可以尝试使用反射将函数替换为模拟。 Mockito 有一个 Whitebox
class 封装了其中的一些:
Function<Throwable, Optional<String>> mockFunc = Mockito.mock(Function.class);
Whitebox.setInternalState(MyClass.class, "SOME_FUNCTION", mockFunc);
// ... test code ...
verify(mockFunc, times(2)).apply(any(Exception.class));
但这很可能会产生一些不必要的副作用(例如 SOME_FUNCTION
模拟时间比预期的长),并且只能作为最后的手段。