java - 如何为在 run() 中具有无限循环的 Runnable java 类编写 UT?

标签 java unit-testing testing

我有一个如下所示的 java 类。它的工作是监视一个文件,如果该文件的大小在一定时间间隔内没有变化,它就会发出警报。

我想为它写两个UT。

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

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

当条件满足或不满足时,UT 将验证 alerter.alert() 或 alerter.harmless() 是否真的被调用。我 mock 了 Alerter 并将其传递给 Task 的构造函数。但是如何控制run()的时机呢?我知道无法准确控制多线程的时间。我只想知道为这类类(class)编写 ut 的最佳做法是什么。如果可能,请写一个测试样本。

您可以将“某些条件”视为检查指定文件的大小是否以特定时间间隔发生变化。如果不改变,某些条件将为真。

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();

}

提前致谢。

最佳答案

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

还有一个提示。你应该防止你的测试被卡住。 JUnit 和 TestNG 都有定义测试超时的注解。如果超时过期,测试将被框架终止并自动失败。

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

关于java - 如何为在 run() 中具有无限循环的 Runnable java 类编写 UT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7512365/

相关文章:

angularjs - 如何模拟单元测试的配置阶段提供程序?

python - 模拟和猴子修补有什么区别?

javascript - 如何测试 css(3) 样式属性值支持、重复值支持?

ANDROID:查询网络频段频率信息

java - 为什么我们通常使用||结束 |?有什么区别?

java - 使用注释 @DataJpaTest 进行测试 - EmbeddedDatabaseType 是必需的

java - 是否可以在 Fresco Lib 上加载 SVG?

testing - 如何在 VSTS 的测试配置中设置浏览器?

java - 打印整数列表的列表

java - 使用 Ajax 的 RESTFul Web 服务