如何验证某事是某些遗嘱执行人的尸体



给定某些类的以下实现:

private Executor someSpecialExecutor;
private SomeService someService;
public void foo() {
    someSpecialExecutor.execute(() -> someService.bar());
}

假设someSpecialExecutor始终在当前线程中同步运行传递的运行,我该如何验证someService.bar()当前在someSpecialExecutor中运行而不是在其外部运行时?

我知道我可以创建一个实现Runnable的类,并检查执行程序是否通过此类的实例,并在Runnable实现的测试中检查someService.bar()的调用。但是我想避免为此目的创建其他类。

好吧,您可以确保someService.bar()仅在测试中被调用一次,这是verify的默认值:

Mockito.verify(someService).bar();

如果被称为多次,这将失败。更确定的另一种方法是嘲笑执行权限本身,然后使用ArgumentCaptor

ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
Mockito.verify(someSpecialExecutor).execute( captor.capture() );
Mockito.verify(someService, Mockito.never()).bar(); // nothing has been executed yet
Runnable runnable = captor.getValue(); // get the actual argument
runnable.run(); // execute the runnable 
Mockito.verify(someService).bar(); // now the lambda should have executed the method

以这种方式,您可以模拟执行者,然后检查执行方法是否被调用一次(不实际执行某些内容)。此时,不应调用someService.bar()方法。不,您会收到传递给执行人并执行它的参数 - 现在应该调用一次someService.bar()。

,因为您说 someSpecialExecutor将始终在当前线程中同步运行传递的 Runnable,因此您可以检查someService.bar()内的当前调用堆栈以确定该方法是否在someSpecialExecutor实例中运行S类。

class SomeService {
    public void bar() {
        // check whether we've been called by 'someSpecialExecutor'
        boolean inside = false;
        StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
        for (StackTraceElement frame : callStack) {
             if (frame.getMethodName().equals("execute") &&
                 frame.getClassName().equals(someSpecialExecutor.getClass().getName())) {
                 inside = true;
                 break;
             } 
        }
        System.out.println("bar: " + inside);
    }
}

但是,这并不一定保证您在someSpecialExecutor中,可能是代码是由同一类的某些不同实例执行的。

但是,通过扩展上述方法,您可以进一步测试呼叫堆栈,看看您是否在foo()中,这为您提供了更强的保证。

相关内容

  • 没有找到相关文章

最新更新