0

I'm working on testing a certain class that utilises a WatchService. This class has a method, processEvents, that works something like this (from 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;
    }
}

So it has an infinite loop and needs to run in its own thread. Now I'm trying to test the "do something" part, but I'm unsure how. This test method for example shouldn't fail:

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

Edit: Clarification, getEvents shouldn't be empty(because a file has been created) and this even gets detected by the watchservice (a print gets done). But because it runs in a different thread, the test reports it as being empty, so it fails because isEmpty shouldn't be true in the assertFalse.

2
  • So what's the problem, exception or output you're getting? Commented Nov 17, 2013 at 11:52
  • My excuses, clarification has been added. Commented Nov 17, 2013 at 16:02

2 Answers 2

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

I guess 5 seconds should be long enough?

Also, you might need to make getEvents synchronized or something.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't think that does it. I've made getEvents synchronized and implemented exactly as you have given it to me, but tests fails.
would need to see more code to see if you are doing the synchronization right.
0

The easiest solution is to only test AddToEvents(event) code in isolation.

Create mock events and then call your AddToEvents(event) and test to make sure you do the right thing.

This has the added benefit of being able to mock events which would be hard to simulate in a real-word environment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.