【问题标题】:Testing asynchronous code with JUnit使用 JUnit 测试异步代码
【发布时间】:2012-01-18 00:29:47
【问题描述】:

我想测试一些依赖网络传输的代码。代码发出请求并提供回调 - 当请求完成时,回调被触发。我想模拟出网络传输,并使用Thread.sleep 来模拟一些延迟......但这当然会使整个测试暂停。

到目前为止,我一直在创建新线程并在整个测试过程中使用CountDownLatches 来阻止测试在触发回调之前结束。我的模拟网络对象创建了一个新线程,在该线程上休眠,然后触发回调。这实际上工作得很好,但问题是回调中的任何断言错误都不会报告给原始的 junit 线程 - 相反,我在控制台上收到异常文本,它更难理解和使用。

我希望有一个:

  1. 一种将assertEquals 输出从衍生线程传送到主JUnit 输出收集器的方法,或者
  2. 在 JUnit 中测试线程代码的完全不同且更好的方法,或
  3. 在单线程中模拟异步代码的某种方式

感谢您的任何想法!

【问题讨论】:

标签: java multithreading testing junit


【解决方案1】:

当我不得不实现类似于你的异步机制时,我创建了抽象类AsyncTestCase,它包含测试错误并提供特殊方法waitForCallback()。当异步任务在预期结果中发现错误时,它会将错误放入此变量中。 setter 对waitForCallback() 使用的对象调用notify()。因此,当回调到达时,它会立即导致测试唤醒。然后我可以调用所有断言,包括由异步任务存储的断言。

并且不要忘记在测试中设置超时以防止它们永远休眠:

@Test(timeout=10000)
public void mytest() {
    callAsyncTask();
    waitForAsyncTask();       // from base class
    assertAsyncTaskResult();  // from base class
}

【讨论】:

    【解决方案2】:

    您所描述的是ConcurrentUnit。这是一个例子:

      final Waiter waiter = new Waiter();
    
      new Thread(() -> {
        doSomeWork();
        waiter.assertTrue(true);
        waiter.resume();
      }).start();
    
      // Wait for resume() to be called
      waiter.await(1000);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-12
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多