【问题标题】:How to unit test a method that simply starts a thread with jUnit?如何对仅使用 jUnit 启动线程的方法进行单元测试?
【发布时间】:2012-06-18 09:51:19
【问题描述】:

如标题所示,我想测试一个这样的方法:

public void startThread()
{
    new Thread()
    {
        public void run()
        {
            myLongProcess();
        }
    }.start();
}

编辑: 从 cmets 来看,我想测试线程是否启动并不常见。所以我必须调整问题......如果我的要求是 100% 的代码覆盖率,我是否需要测试该线程是否启动?如果是这样,我真的需要一个外部框架吗?

【问题讨论】:

标签: java multithreading unit-testing testing junit


【解决方案1】:

这可以通过Mockito 优雅地完成。假设该类名为 ThreadLauncher,您可以确保 startThread() 方法导致调用 myLongProcess()

public void testStart() throws Exception {
    // creates a decorator spying on the method calls of the real instance
    ThreadLauncher launcher = Mockito.spy(new ThreadLauncher());

    launcher.startThread();
    Thread.sleep(500);

    // verifies the myLongProcess() method was called
    Mockito.verify(launcher).myLongProcess();
}

【讨论】:

  • 我认为模拟或监视被测类是一种不好的做法。相反,请验证 myLongProcess 的作用。它必须做一些事情,验证它。如果它正在调用其他类,则模拟该类以验证调用。
  • 我对这个问题的理解是他想测试startThread() 方法是否可以启动线程。他没有问如何测试myLongProcess() 的结果,我假设他已经知道如何做到这一点。
  • 如果您的目标是 100% 的覆盖率,则必须在测试中执行 startThread() 方法。您可以按照我的建议执行此操作,或者如果您不想在项目中导入 Mockito,请检查 myLongProcess() 的执行结果。困难在于等到方法完成来检查结果。
  • Thread.sleep 可能会导致套件中的其他测试不稳定并莫名其妙地失败
  • @AmitDash 怎么样?你有例子吗?
【解决方案2】:

如果您需要 100% 的覆盖率,您将需要调用 startThread,这将启动一个线程。我建议对线程进行某种验证(通过验证myLongProcess 中的某些事情正在发生,然后清理线程。然后您可能会通过直接从你的单元测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多