对于Junit问题:测试多个线程时

时间:2013-10-15 12:21:34

标签: java multithreading junit assert

我使用JDK ScheduledThreadPoolExecutor来完成计划工作。我给出了如下简单的代码。

 class Job implements  Callable<Void>{
         public Long id;

        @Override
        public Void call() throws Exception {
            if (!isOk(id)) {
                return null;
            }

            _context.exe(id);
            return null;
        }


        void setId(Long id) {
            this.id = id;
        }
    }

每次我添加这份工作来安排服务:

public void schedule() {
    Job job = new Job();
    job.setId(1L);;
    _scheduledExecutor.schedule(job, 1000, TimeUnit.MILLISECONDS) ;
}

此作业将延迟调用上下文的exe方法。 我的问题:我想要断言_context的exe方法是否被调用?我怎么能这样做?

我目前正在做什么,我尝试添加登录call()方法并通过我的眼睛验证UT。 PS:对于这个UT,我也尝试模拟_context的exe方法,但是在其他线程中运行作业,所以我无法在当前线程中断言它。有谁有想法帮我写这个案子的断言?

目前我在以下方式做,但我仍然认为有更好的解决方案,只是我不知道。

_context是Context的实例,我从这个类扩展。

public class UTContext extends Context {
public UTTestCase utTestCase ;

@Override
public void  exe(Long id) {
    utTestCase.setIsCall(true);  
}

public void setUtTestCase(UTTestCase utTestCase) {
    this.utTestCase = utTestCase;
}

}

然后我将在UT中声明isCall var。

有人对此有好主意,请给我回答。非常感谢你。

3 个答案:

答案 0 :(得分:2)

您正在测试调用层次结构的中间部分,即线程创建者/调度程序代码。这意味着您必须从顶部驱动代码并从顶部或底部进行测试。有多种模式可供您使用。

您可以检测底部(exe(id))或从顶部进行测量。由于调度延迟,从顶部开始测量变得非常困难。

exe()有副作用吗?这个副作用是否可以从您的测试代码中测试?你能推断一次exe()调用的操作吗?你能推断一个以上的调用吗?如果其中任何一个的答案都是“否”,那么你将不得不走得更远。

@RamonBoza提供了一个很好的解决方案。

您还可以创建类Job的可测试版本,因此:

class JobUT extends Job {
  @Override
  public Void call() throws Exception {
    Void result = super.call();
    // Report error if wrong return result
  }
}

(我知道上面的代码存在问题,因为Void未正确处理。我无法重构您的代码。)

您也可以使用面向方面编程实现相同的目标,在完成并执行相同测试后,您可以拦截调用。

答案 1 :(得分:0)

对于多线程断言,我通常创建'N'个线程,并为每个线程分配不同的值。

然后将它们全部加入,最后只检查每个线程的数据是否存储?例如。

想象一下,你创建了1000个线程来存储一个整数到数据库,所以在这1000个线程完成后你必须检查数据库中是否存储了所有数据。

更严格的测试是集成测试,应该使用不同的场景和中间件(OpenNebula,亚马逊云等)。

答案 2 :(得分:0)

服务器一天之后,我知道如何验证它。我附上其他问题以供参考:

Assert times of expectLastCall

Service service = EasyMock.createMock(Service.class);
service.applyInitialDump(entities);
EasyMock.expectLastCall().times(100);

processor.processInitialDump(entities)
EasyMock.verify(service);