title: Using JMockit to return actual instance from mocked constructor
body: <p>I've looked at the following question and it is not the same as mine:</p>
  
  <p><a href="https://stackoverflow.com/questions/8060735/jmockit-how-to-expect-constructor-calls-to-mocked-objects">jMockit: How to expect constructor calls to Mocked objects?</a></p>
  
  <p>This question is similar but the answer is not helpful to me:</p>
  
  <p><a href="https://stackoverflow.com/questions/4563584/how-to-mock-the-default-constructor-of-the-date-class-with-jmockit">How to mock the default constructor of the Date class with JMockit?</a></p>
  
  <p>What I am trying to do is mock a constructor call to <code>java.util.zip.ZipFile</code>, specifically the one that has a <code>java.io.File</code> argument. I would like for the constructor to return an instance of a different <code>ZipFile</code>, one I will instantiate with the constructor that only takes a <code>String</code> argument. </p>
  
  <p>This constructor call takes place inside a method under test, so I can't inject the <code>ZipFile</code> I want as a parameter.</p>
  
  <p>For example, the code looks something like this:</p>
  
  <pre><code>public void whatever() {
     //some code
     //some more code
     foo();
     //yet more unrelated code
  }
  
  private Blah foo() {
      ZipFile zf;
      //a bunch of code we don't care about
  
      zf = new ZipFile(someFile);// I want to give it a known zipfile! mock this!
  
  
      // some more code we don't care about
  
      Enumeration&lt;?&gt; entries = zf.entries();
      ZipEntry entry = (ZipEntry) entries.nextElement();
      InputStream is = zf.getInputStream(entry)
      //maybe some other calls to the ZipFile
  
      // do something else
  }
  </code></pre>
  
  <p>My first thought was to do the following with static partial mocking:</p>
  
  <pre><code>final ZipFile test = new ZipFile("path/to/actual.zip");
  new NonStrictExpectations() {
      @Mocked("(java.io.File)")
      ZipFile zf;
      {
          new ZipFile((File) any); result = test;
      }
  };
  </code></pre>
  
  <p>But this won't work as indicated by this line in the tutorial: <code>constructors have void return type, so it makes no sense to record return values for them</code></p>
  
  <p>My second thought was to try the following:</p>
  
  <pre><code>new NonStrictExpectations() {
      {
          newInstance("java.util.zip.ZipFile", new File("path/to/actual.zip"));
      }
  };
  </code></pre>
  
  <p>But this throws the following when trying to initialize the file:</p>
  
  <pre><code>java.util.zip.ZipException: error in opening zip file
  at java.util.zip.ZipFile.open(Native Method)
  at java.util.zip.ZipFile.&lt;init&gt;(Unknown Source)
  at java.util.zip.ZipFile.&lt;init&gt;(Unknown Source)
  </code></pre>
  
  <p>My third thought was to use a <code>@MockClass</code> as below:</p>
  
  <pre><code>@Before
  public void setUp() throws Exception {
      Mockit.setUpMocks(MockedZipFile.class);
  }
  @After
  public void tearDown() {
      Mockit.tearDownMocks();
  }
  
  @MockClass(realClass=ZipFile.class)
  public static class MockedZipFile {
      public ZipFile it;
      @Mock
      public void $init(File f) throws ZipException, IOException {
          it = new ZipFile("path/to/actual.zip");//this is what would be called
      }
  }
  </code></pre>
  
  <p>But this hoses some other mocks I have that load a configuration file for a different part of my test class. Not to mention I will want different zip files for different test cases.</p>
  
  <p>I suppose I could mocking <strong>everything</strong> the <code>ZipFile</code> would do, but this would quickly become a giant pain as it's called lots of places, it's output would be need to be mocked, etc, etc. Refactoring to try to make this accessible would be awkward, as the code that uses the <code>ZipFile</code> is internal to the code and the public methods don't really care about it. </p>
  
  <p>I have a feeling there is a way for JMockit to allow this (giving a particular instance of an object when a constructor is called), but I can't figure it out. Does anyone have any ideas?</p>
  
  <p>EDIT: I tried the method suggested by @Rogerio, but I have a new error. Here's my setup:</p>
  
  <pre><code>final ZipFile test = new ZipFile("path/to/actual.zip");
  new NonStrictExpectations() {
      ZipFile zf;
      {
          zf.entries();
          result = test.entries();
          zf.getInputStream((ZipEntry) any);
          result = new Delegate() {
              InputStream getInputStream(ZipEntry entry) throws IOException {                 
                  return test.getInputStream(entry);
              }
          };
      }
  };
  </code></pre>
  
  <p>but I get the following stack trace:</p>
  
  <pre><code>java.lang.InternalError
  at path.to.test.ExtractDataTest$1.&lt;init&gt;(ExtractDataTest.java:61)
  at path.to.test.ExtractDataTest.setUp(ExtractDataTest.java:61)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
  </code></pre>
  
  <p>where line 61 is the <code>new NonStrictExpectations() {</code> line. </p>
  
  <p>I really want to say "instead of mocking this object, substitute this other object of the same type". Maybe I have expressed that poorly.</p>
  
  <p>EDIT2: I figured I should include version numbers:
  Using Eclipse 3.6.1
  Java 1.6.0_26
  JMockit 0.999.10</p>