我如何在单元测试中验证方法将异步执行,即在单独的线程中执行?

How can I verify in a unit test that a method will be executed asynchronously i.e. in a separate thread?

以下方法同步调用 service 的方法 serveThis(),并在单独的线程中调用方法 serveThat(),即异步调用:

public void doSomething() {
    service.serveThis();
    new Thread(() -> service.serveThat()).start();
}

我想在单元测试中验证 service.serveThat() 将异步执行,因为根据规范它不能同步执行。 所以,我想防止以后有人像这样删除开始一个新线程:

public void doSomething() {
    service.serveThis();
    // This synchronous execution must cause the test to fail
    service.serveThat();
}

为了实现这一点,我使用 Mockito:

Thread threadServeThatRunsOn;

@Test
public void serveThatWillBeExecutedAsynchronously() throws Exception {
    doAnswer(invocation -> {
        threadServeThatRunsOn = Thread.currentThread();
        return null;
    }).when(mockService).serveThat();

    testObject.doSomething();

    verify(mockService, timeout(200)).serveThat();
    assertNotEquals(threadServeThatRunsOn, Thread.currentThread());
}

现在,如果有人修改 doSomething() 以便 service.serveThat() 同步 运行,那么此测试将失败。

I want to verify that service.serveThat() will be executed asynchronously.

会的。语法是这样说的。不要测试平台。

可以在代码中的任何地方得到 Thread.currentThread(),所以你可以写这样的东西并基于它做出断言(如果你没有[,你可以用不同的方式用 Mockito 实现这个 YourInterface):

public class ThreadChecker implements YourInterface {

    volatile Thread serveThisThread;
    volatile Thread serveThatThread;

    public void serveThis() {
        serveThisThread = Thread.currentThread();
    }

    public void serveThat() {
        serveThatThread = Thread.currentThread();
    }
}

单元测试可以是这样的,但根据用例可能需要额外的断言:

ThreadChecker mockService = new ThreadChecker(); 

@Test
public void serveThatWillBeExecutedAsynchronously() throws Exception {
    doSomething();
    TestCase.assertFalse(mockService.serveThatThread == mockService.serveThisThread);
}