如何为runnable java类编写一个UT,它在run()中有一个无限循环?

时间:2011-09-22 09:14:38

标签: java unit-testing testing

我有一个像下面这样的java类。它的工作是监视一个文件,如果该文件的大小没有以一定的间隔改变,它将引发警报。

我想为它写两个UT。

1.模拟文件大小保持不变。

2.模拟文件大小会保持一段时间的变化。之后文件大小会改变。

UT将验证a​​lerter.alert()或alerter.harmless()是否在条件满足或未满足条件时被调用。我嘲笑Alerter并将其传递给Task的构造函数。但是如何控制run()的时间?我知道多线程的时间不能准确控制。我只想知道为这类课程写出最佳做法是什么。如果可能,请写一个测试样本。

您可以将“某些条件”视为检查指定文件的大小是否以特定间隔更改。如果没有改变,某些条件将成立。

class Task implements Runnable{
    Alerter alerter;
    boolean stop=false;
    public Task(Alerter alerter){
        this.alerter=alerter;
    }
    public void run() {
        while (!stop){

            if (some condition){
                alerter.alert();
            } else{
                alerter.harmless();
            } 

            Thread.sleep(5000);

        }
    }
    public synchronized void stop(){
        stop=true;
    }

}

我正在考虑写下面的uts。但我认为这不够好。

@Test
public void testRunWithFeed() {
    Alerter mockAlerter=mock(Alerter.class);
    Task task=new Task(mockAlerter);
    Thread thread =new Thread(task);
    thread.start();
    try {
        Thread.sleep(1000); // give Task.run() a change to run
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    task.stop();
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    verify(mockAlerter,atLeastOnce()).alert();
    verify(mockAlerter,never()).harmless();

}

@Test
public void testRunNoFeed() {
    Alerter mockAlerter=mock(Alerter.class);
    Task task=new Task(mockAlerter);
    Thread thread =new Thread(task);
    thread.start();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    changeFileSize();
    try {
        Thread.sleep(6000); //because every 5000ms file size will be checked once in run()
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    task.stop();
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    verify(mockAlerter,atLeastOnce()).alert();
    verify(mockAlerter,atLeastOnce()).harmless();

}

提前致谢。

1 个答案:

答案 0 :(得分:1)

我认为你不应该叫sleep(),显然不应该在测试中调用stop。 如果任务运行并且预期终止调用join()就足够了:主线程将等到工作线程完成。然后你将验证结果。

又一个提示。你应该防止测试卡住。 JUnit和TestNG都有注释来定义测试超时。如果超时到期,测试将被框架杀死并自动失败。

例如对于JUnit,属性为timout@Test(timeout=3000)表示3秒。