有没有办法在不阻塞线程的情况下暂停单元测试

时间:2011-12-08 03:50:18

标签: java unit-testing playframework

我正在使用播放1.2.4而我正在尝试设置单元测试以测试作业。 我的工作每2秒运行一次,并根据某些条件更改某些对象的状态。这就是我用来做这件事。

@Every("2s")
public class GameScheduler extends Job {
    public void doJob(){
        //Fetch of object from db and status change based on conditions happens here
    }
}

现在在我的单元测试中,我设置了这些条件,但是我希望测试在获取其中一个设置对象之前等待3秒并执行断言等于其状态以查看作业是否正确...

如果我使用

pause(3000);

或类似

try {
    Thread.sleep(3000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

测试停止但作业也停止了。似乎工作和测试都在同一个线程上。有没有办法在不停止工作的情况下暂停测试?类似于控制器中的await()方法

2 个答案:

答案 0 :(得分:3)

您不需要测试调度程序,因为它应该可以工作(因为框架正在处理它)。您需要的只是测试doJob方法是否正在执行其工作。所以,只需编写一个这样的测试:

GameScheduler job = new GameScheduler();
job.doJob();

// assert whatever you want here

答案 1 :(得分:0)

虽然简单地测试作业(不等待调度程序为你运行它)会在大多数情况下做到这一点(读作:可能是所有情况),有些情况下可能会感兴趣的是不必触发手动。

例如,您有一组共享公共配置集的播放应用程序。在一个从站中更改一个配置,所有其他配置记录并执行相同操作。假设配置保存在memcached中。一个有用的单元测试是使用Cache.set手动更改某些设置,等待configurationObserver作业运行所花费的时间,然后检查内部配置是否已更新。如果有一系列作业更新配置等,这将更有帮助。

要做到这一点,你必须记住在DEV模式下播放使用一个线程(这有助于调试很多,顺便说一句)。你可以简单地将这一行添加到你的application.conf:%test.application.mode = prod,你将拥有多个线程。

稍后编辑:在这种情况下,将模式设置为prod似乎并没有帮助。这有什么帮助:使用一些“等待”魔法。

@Test
public void myTest() { 
    final Lock lock = new ReentrantLock();
    final Condition goAhead = lock.newCondition();
    /* Here goes everything you need to do before "pausing" */
    lock.lock();
    try {
        /**
         * Set whatever time limit you want/need 
         * You can also use notifiers like goAhead.signal(), from within another thread 
         */   
        goAhead.await(5, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        assertTrue(whateverINeedToTest);
    } finally {
        lock.unlock();
    }
}