测试线程代码java

时间:2013-11-17 11:39:08

标签: java multithreading junit

我正在测试使用WatchService的某个类。这个类有一个方法,processEvents,它的工作原理是这样的(来自http://docs.oracle.com/javase/tutorial/essential/io/notification.html):

for (;;) {
    WatchKey key;
    try {
        key = watcher.take();
    } catch (InterruptedException x) {
        return;
    }
    for (WatchEvent<?> event: key.pollEvents()) {
        WatchEvent.Kind<?> kind = event.kind();
        // This key is registered only
        // for ENTRY_CREATE events,
        // but an OVERFLOW event can
        // occur regardless if events
        // are lost or discarded.
        if (kind == MODIFY) {
            //Do something
            AddToEvents(event);
        }
    }
    boolean valid = key.reset();
    if (!valid) {
        break;
    }
}

所以它有一个无限循环,需要在自己的线程中运行。现在我正在尝试测试“做某事”部分,但我不确定如何。例如,这种测试方法不应该失败:

@Test
public void testEventAdded() {
    Thread thread = new Thread() {
        @Override
        public void run() {
            synchronized(currentThread) {
                MyClass.processEvents();
            }
        }
    };
    thread.start();
    File tempFile = File.createTempFile("temporary file", null, Paths.get(testdirectory).toFile());
    tempFile.deleteOnExit();
    assertFalse(MyClass.getEvents().isEmpty());
}

编辑:澄清,getEvents不应为空(因为已经创建了一个文件),这甚至会被watchservice检测到(打印完成)。但是因为它在不同的线程中运行,测试报告它是空的,所以它失败了,因为在assertFalse中isEmpty不应该为真。

2 个答案:

答案 0 :(得分:1)

    File tempFile = File.createTempFile("temporary file", null, Paths.get(testdirectory).toFile());
    tempFile.deleteOnExit();
    Thread.sleep(5000);
    assertFalse(MyClass.getEvents().isEmpty());

我猜5秒应该够长吗?

此外,您可能需要将getEvents同步或其他内容。

答案 1 :(得分:0)

最简单的解决方案是仅隔离测试AddToEvents(event)代码。

创建模拟事件,然后调用AddToEvents(event)并测试以确保您做正确的事。

这样做的另一个好处是能够模拟在真实环境中难以模拟的事件。