jmockit / jmockit1

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

$init(Invocation) only fakes the 0-parameter constructor, contrary to Mock documentation #739

Open lewisb42 opened 1 year ago

lewisb42 commented 1 year ago

Please provide the following information:

This does not hold true for constructors when faking via $init. I.e., public void $init(Invocation inv) will only match the zero-parameter constructor, not those having parameters.

Sample code:

`// class being faked public class MyClass { private int x;

public MyClass() {
    x = 0;
}

public MyClass(int x) {
    this.x = x;
}

}`

`// test class class TestInit { @Test void test() {

    var fakedMyClass = new MockUp<MyClass>() {
        boolean calledZeroParam = false;
        boolean calledOneParam = false;

        @Mock
        public void $init(Invocation inv) {
            if (inv.getInvokedArguments().length == 0) {
                calledZeroParam = true;
            }

            if (inv.getInvokedArguments().length == 1) {
                calledOneParam = true;
            }

            inv.proceed();
        }
    };

    MyClass zeroParam = new MyClass();
    MyClass oneParam = new MyClass(42);

    assertAll(
            () -> assertTrue(fakedMyClass.calledZeroParam),
            () -> assertTrue(fakedMyClass.calledOneParam) // <- fails here
        );
}

} `

cyqw commented 1 year ago

You should provide arguments for $init after Invocation with the same type of arguments in target constructor. like this

        @Mock
        public void $init(Invocation inv, int x) {
lewisb42 commented 1 year ago

I would have already done that, except I have a situation where I don't know beforehand what the constructor signatures will be. According to the docs, I should be able to intercept all constructors without specifying their formal parameters. I can already do so with any named method, and in fact for all methods (except constructors) with $advice().

You should provide arguments for $init after Invocation with the same type of arguments in target constructor. like this

      @Mock
      public void $init(Invocation inv, int x) {