jmockit / jmockit1

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

Mocking constructor. #59

Closed evdzhan closed 10 years ago

evdzhan commented 10 years ago

Hi yet again,

Environment - JDK 1.7.0_51 32 bit Win7 64 bit JMockit 1.11

I have two issues to report. I think they are connected with each other.

ISSUE 1 - Original constructor gets called along with the mocked one. The thing is that when I mock a constructor the original constructor gets invoked, which is not something that I want. And my understanding is that this is not intended behaviour.

My test class is the following

import mockit.Mock; import mockit.MockUp; import mockit.integration.junit4.JMockit; import org.junit.Test; import org.junit.runner.RunWith;

@RunWith(JMockit.class) public class TestJohn { @Test public void createJohn() { new MockJohn(); new John(); } public class MockJohn extends MockUp { @Mock public void $init() { System.out.println("John was mocked!"); } } }

And my John class

public class John { public John(){ System.out.println("I am John"); } }

There is a workaround to this problem by making the MockJohn class not public, i.e. make it package default like this

@RunWith(JMockit.class) public class TestJohn { @Test public void createJohn() { new MockJohn(); new John(); } class MockJohn extends MockUp { @Mock public void $init() { System.out.println("John was mocked!"); } } }

ISSUE 2 - My second issue is that when I have John and MockJohn classes inside the TestJohn class, I am getting the following error : ava.lang.IllegalArgumentException: Matching real methods not found for the following mocks

Here is the code :

import mockit.Mock; import mockit.MockUp; import mockit.integration.junit4.JMockit; import org.junit.Test; import org.junit.runner.RunWith;

@RunWith(JMockit.class) public class TestJohn { class John { public John(){ System.out.println("I am John"); } }

@Test
public void createJohn() {
    new MockJohn();
    new John();
}

class MockJohn extends MockUp<John> {
    @Mock public void $init() {
        System.out.println("John was mocked!");
    }
}

}

rliesenfeld commented 10 years ago

Hi,

The first problem is indeed a bug, which will be fixed for release 1.12.

The second, though, is just that the "John" class, when put inside the test class and without being made "static", becomes an inner class; therefore, its constructor has the implicit signature of "(TestJohn)", with one parameter for the outer object. So, the corresponding @Mock method would need to have a matching parameter.