java - 测试异步方法调用

标签 java testing junit integration-testing

下面是我的应用程序的简化设置。它有一个 Foobar 类,它调用一个 facade 方法来获取数据。然后,外观调用 Web 服务以实际获取数据,然后对数据进行一些操作,然后将其返回给 Foobar。

现在因为 Web 服务可能需要很长时间才能运行,所以对外观的方法调用需要是异步的。因此,外观的方法没有返回值,而是该方法使用回调对象。查看示例并继续阅读下文。

public class Foobar {
    private List<DTO> dtos;

    @Autowired
    private Facade facade;

    public void refresh() {
        facade.refreshFoobar(new CallBack() {
            public void dataFetched(List<DTO> dtos) {
                setDtos(dtos);
            }

        });
    }    

    public void setDtos(List<DTO> dtos) {
        this.dtos = dtos;
    }
}


public class Facade {

    ...

    public void refreshFoorbar(CallBack cb) {
        // Fetch data from a web service
        List<DTO> dtos = webService.getData();  
        // Manipulate DTOs
        ....
        // call on the callback method
        cb.dataFecthed(dtos);
    }

}

我有两种方法可以使 facade 的方法异步,通过手动创建线程或使用 springs @Async 注释。

public class Facade {

    public void refreshFoorbar(CallBack cb) {
        new Thread() {

            @Override
            public void run() {
                ....
            }

        }.start();

    }
}

// ... OR ...

public class Facade {

    @Async
    public void refreshFoorbar(CallBack cb) {
        ....    
    }
}

我的问题是我现在需要为这个方法调用链编写一个集成测试。我想我需要在运行集成测试时强制异步外观调用同步,否则我不确定何时可以执行适当的断言。使方法调用同步的唯一想法是使用手动处理的线程并使线程有条件(因此,出于测试目的,我有一个 if 子句来确定外观方法是否应在单独的线程中运行)。

但是,我觉得可能有更好的解决方案来解决我的问题,无论是强制方法同步的更好方法(例如使用 spring),还是通过某种方式测试多线程。

这是我需要你的建议的地方,你会如何解决我的问题?请注意,我将 junit 用于单元测试和集成测试。

最佳答案

简单的解决方案是像这样返回一个 Future 对象,

@Async
public Future<String> refreshFoorbar(CallBack cb) {
    yourHeavyLifting(); //asynchronous call
    return new AsyncResult<String>("yourJobNameMaybe");   
}

在您的测试中,获取 future 的引用并调用 get()方法。

future.get(); // if its not already complete, waits for it to complete
assertTrue(yourTestCondition)

blog post显示示例。

关于java - 测试异步方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7594354/

相关文章:

java - 文件的线程安全

java - 优化 Hibernate session.createQuery().list();

java - 使用莱布尼茨级数求 pi 值

android - Robotium - Eclipse 中的 API 错误

Java - Spring Integration Mock SftpServer 错误

java - 使用 Jax-RS 发布

python - 断言错误 : 302 ! = 200

python - 使用单击选项 python 测试 cli 命令

java - 如何将 JUnit TemporaryFolder @Rule 与 Spring @Value 属性一起使用?

java - 按指定顺序运行 Maven 项目的 JUnit 测试