title: Spock - mock a Groovy closure method?
body: <p>This is what I want to do:</p>
  
  <pre><code>def mockSubdirs = []
  mockSubdirs &lt;&lt; Mock( File ){
      getName() &gt;&gt; 'some subdir'
      lastModified() &gt;&gt; 2000
  }
  ...
  
  File mockParentDir = Mock( File ){
      getName() &gt;&gt; 'parent dir'
      eachDir() &gt;&gt; mockSubdirs.iterator() // ??? NB eachDir is a GDK method
      // I tried things along these lines:
      // listFiles() &gt;&gt; mockSubdirs
      // iterator() &gt;&gt; mockSubdirs.iterator()
  }
  
  cut.myDirectory = mockParentDir
  </code></pre>
  
  <p>The app code is like this:</p>
  
  <pre><code>def dirNames = []
  myDirectory.eachDir{ 
      dirNames &lt;&lt; it.name
  }
  </code></pre>
  
  <p>All the above give <code>FileNotFoundException</code> on the <code>myDirectory.eachDir{</code> line...</p>
  
  <p><strong><em>later</em></strong></p>
  
  <p>Thanks to all 3 answerers for possible solutions to this.  Kriegaex's code example doesn't seem to work for me, and I'm not sure why.  However his suggestion of looking at the Groovy source code is great. So in NioGroovyMethods.java I find that <code>eachDir</code> calls <code>eachFile</code> which looks like this:</p>
  
  <pre><code>public static void eachFile(final Path self, final FileType fileType, @ClosureParams(value = SimpleType.class, options = "java.nio.file.Path") final Closure closure) throws IOException {
          //throws FileNotFoundException, IllegalArgumentException {
      checkDir(self);
  
      // TODO GroovyDoc doesn't parse this file as our java.g doesn't handle this JDK7 syntax
      try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(self)) {
          for (Path path : stream) {
              if (fileType == FileType.ANY ||
                      (fileType != FileType.FILES &amp;&amp; Files.isDirectory(path)) ||
                      (fileType != FileType.DIRECTORIES &amp;&amp; Files.isRegularFile(path))) {
                  closure.call(path);
              }
          }
      }
  }
  </code></pre>
  
  <p>... so my first thought was to try to mock <code>Files.newDirectoryStream</code>.  <code>Files</code> is <code>final</code>, so you have to use a <code>GroovyMock</code>, and because the method is <code>static</code> you would appear to have to use something like this:</p>
  
  <pre><code>GroovyMock( Files, global: true )
  Files.newDirectoryStream(_) &gt;&gt; Mock( DirectoryStream ){
      iterator() &gt;&gt; mockPaths.iterator()
  }
  </code></pre>
  
  <p>... attempts along these lines don't seem to work... I wouldn't be at all surprised to hear from someone that the <code>Files</code> class in the Groovy language mechanism will not be affected by this attempt at a mock...</p>
  
  <p>Then I thought that presumably <code>toPath</code> must be called on the <code>File</code> in question, so tried this:</p>
  
  <pre><code>File mockParentDir = Mock( File ){
      toPath() &gt;&gt; {
          println "toPath called"
          Mock( Path )
      }
  }
  </code></pre>
  
  <p>... this line is not printed.  OK I'm a bit stumped: to get a <code>Path</code> from the <code>File</code> I give it the Groovy mechanism must be using something sneaky: maybe something like <code>getAbsolutePath()</code>... and then creating a <code>Path</code> from the resulting <code>String</code>? This would require more examination of the source code... but if this is the case, you wouldn't then be able coerce Groovy to use a mock <code>Path</code>!
  or... maybe other mysterious Groovy things come into play here: metaclass, etc.?</p>