hazendaz / jmockit1

Advanced Java library for integration testing, mocking, faking, and code coverage
Other
14 stars 6 forks source link

Real constructor called and then mocked constructor called #133

Open MrPottery opened 1 year ago

MrPottery commented 1 year ago

Hi, I am in the process of moving from Java 11 to Java 17. I have switched to JMockit 1.50.0 and am encountering errors in JUnit testing that did not occur in JMockit 1.44 that I was using in Java 11. It appears that for some (not all) mocked constructors, the real constructor is called first, and then the mocked constructor. To illustrate this, I have the following two files. The main program creates a PrintWriter class twice. The first time, it calls with a directory that doesn't exist, and in the second instance, the directory does exist. In the test code, the constructor of PrintWriter is mocked, and simply prints a message logging that it was called. When the code is built with maven and the test is run, the first call to PrintWriter generates a FileNotFoundException but prints no message from the mocked constructor. The second call succeeds and calls the mocked constructor. Here is the main file:

package bugsample;

import java.io.PrintWriter;

public class BugSample {

    public static void main(String[] args) {
        System.out.println( "Running Test 1");

        try (PrintWriter pw = new PrintWriter( "/SomeFile/SomeWhere/missing"))
        {
        }
        catch( Exception e)
        {
            System.out.println( "Caught exception! " + e.getMessage());
            e.printStackTrace();
        }

        System.out.println( "Running Test 2");
        try (PrintWriter pw = new PrintWriter( "/tmp/a"))
        {
        }
        catch( Exception e)
        {
            System.out.println( "Caught exception! " + e.getMessage());
            e.printStackTrace();
        }
        System.out.println( "Done");
    }
}

Here is the test code:


package bugsample;

import org.junit.Test;

import java.io.PrintWriter;

import mockit.*;

public class BugSampleTest
{
    @Test
    public void testMain()
    {
        System.err.println( "Running testcode");

        new MockUp<PrintWriter>()
        {
            @Mock
            void $init( String name)
            {
                System.err.println( "In mocked constructor!");
            }
        };

        String [] args = {"arg1", "arg2"};
        BugSample.main( args);

    }
}
MrPottery commented 1 year ago

Here is the output from the maven build with test:

Running bugsample.BugSampleTest Running testcode Running Test 1 Caught exception! \SomeFile\SomeWhere\missing (The system cannot find the path specified) java.io.FileNotFoundException: \SomeFile\SomeWhere\missing (The system cannot find the path specified) at java.base/java.io.FileOutputStream.open0(Native Method) at java.base/java.io.FileOutputStream.open(FileOutputStream.java:293) at java.base/java.io.FileOutputStream.(FileOutputStream.java:235) at java.base/java.io.FileOutputStream.(FileOutputStream.java:123) at java.base/java.io.PrintWriter.(PrintWriter.java:200) at bugsample.BugSample.main(BugSample.java:10) at bugsample.BugSampleTest.testMain(BugSampleTest.java:27) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at mockit.integration.junit4.JUnit4TestRunnerDecorator.executeTestMethod(JUnit4TestRunnerDecorator.java:157) at mockit.integration.junit4.JUnit4TestRunnerDecorator.invokeExplosively(JUnit4TestRunnerDecorator.java:71) at mockit.integration.junit4.FakeFrameworkMethod.invokeExplosively(FakeFrameworkMethod.java:29) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.runners.ParentRunner.run(ParentRunner.java:292) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365) at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:383) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:344) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:417) Running Test 2 In mocked constructor! Done

hazendaz commented 1 year ago

Up to this point the repo has only had fixes. The original author was notorious at depreciating and immediately deleting. Can you look up change logs, then look to see where it breaks. If it's simply a feature that was deprecated and then deleted, try to revert the deletion to add back support. I know there were many issues after 1.44. I run all my tests in jdk 17 but had to give up on jmockit in many areas.

Few things to note. There are no tags on my fork. Either there never were or the fork I forked from did not have them. I can try to pull them if they exist. If not you want to find the commit dates. It's almost always...deprecated. released, deleted in that order within few commits. Restoring, I since auto formatted so adjustments may need to be made.

Note some items appear simple to restore. For example, I'm going to restore deencapsulation prior to next release. So, in other words, if this was the case and you really want it. Do your best to restore and I'll get it released.

Sent from my Verizon, Samsung Galaxy smartphone Get Outlook for Androidhttps://aka.ms/AAb9ysg


From: MrPottery @.> Sent: Tuesday, June 20, 2023 9:55:25 AM To: hazendaz/jmockit1 @.> Cc: Subscribed @.***> Subject: Re: [hazendaz/jmockit1] Real constructor called and then mocked constructor called (Issue #133)

Here is the output from the maven build with test:

Running bugsample.BugSampleTest Running testcode Running Test 1 Caught exception! \SomeFile\SomeWhere\missing (The system cannot find the path specified) java.io.FileNotFoundException: \SomeFile\SomeWhere\missing (The system cannot find the path specified) at java.base/java.io.FileOutputStream.open0(Native Method) at java.base/java.io.FileOutputStream.open(FileOutputStream.java:293) at java.base/java.io.FileOutputStream.(FileOutputStream.java:235) at java.base/java.io.FileOutputStream.(FileOutputStream.java:123) at java.base/java.io.PrintWriter.(PrintWriter.java:200) at bugsample.BugSample.main(BugSample.java:10) at bugsample.BugSampleTest.testMain(BugSampleTest.java:27) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at mockit.integration.junit4.JUnit4TestRunnerDecorator.executeTestMethod(JUnit4TestRunnerDecorator.java:157) at mockit.integration.junit4.JUnit4TestRunnerDecorator.invokeExplosively(JUnit4TestRunnerDecorator.java:71) at mockit.integration.junit4.FakeFrameworkMethod.invokeExplosively(FakeFrameworkMethod.java:29) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.runners.ParentRunner.run(ParentRunner.java:292) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365) at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:383) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:344) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:417) Running Test 2 In mocked constructor! Done

— Reply to this email directly, view it on GitHubhttps://github.com/hazendaz/jmockit1/issues/133#issuecomment-1598840740, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAHODIYCAXI34RAPJVJAOS3XMGTU3ANCNFSM6AAAAAAZNKNPTI. You are receiving this because you are subscribed to this thread.Message ID: @.***>