title: Unit test code with WatchService
body: <p>Below is a short simple example of using a WatchService to keep data in sync with a file.  My question is how to reliably test the code.  The test fails occasionally, probably because of a race condition between the os/jvm getting the event into the watch service and the test thread polling the watch service.  My desire is to keep the code simple, single threaded, and non blocking but also be testable.  I strongly dislike putting sleep calls of arbitrary length into test code.  I am hoping there is a better solution.</p>
  
  <pre><code>public class FileWatcher {
  
  private final WatchService watchService;
  private final Path path;
  private String data;
  
  public FileWatcher(Path path){
      this.path = path;
      try {
          watchService = FileSystems.getDefault().newWatchService();
          path.toAbsolutePath().getParent().register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
      } catch (Exception ex) {
          throw new RuntimeException(ex);
      }
      load();
  }
  
  private void load() {
      try (BufferedReader br = Files.newBufferedReader(path, Charset.defaultCharset())){
          data = br.readLine();
      } catch (IOException ex) {
          data = "";
      }
  }
  
  private void update(){
      WatchKey key;
      while ((key=watchService.poll()) != null) {
          for (WatchEvent&lt;?&gt; e : key.pollEvents()) {
              WatchEvent&lt;Path&gt; event = (WatchEvent&lt;Path&gt;) e;
              if (path.equals(event.context())){
                  load();
                  break;
              }
          }
          key.reset();
      }
  }
  
  public String getData(){
      update();
      return data;
  }
  }
  </code></pre>
  
  <p>And the current test</p>
  
  <pre><code>public class FileWatcherTest {
  
  public FileWatcherTest() {
  }
  
  Path path = Paths.get("myFile.txt");
  
  private void write(String s) throws IOException{
      try (BufferedWriter bw = Files.newBufferedWriter(path, Charset.defaultCharset())) {
          bw.write(s);
      }
  }
  
  @Test
  public void test() throws IOException{
      for (int i=0; i&lt;100; i++){
          write("hello");
          FileWatcher fw = new FileWatcher(path);
          Assert.assertEquals("hello", fw.getData());
          write("goodbye");
          Assert.assertEquals("goodbye", fw.getData());
      }
  }
  }
  </code></pre>