Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
2 tasks
lewisb42 opened this issue Feb 6, 2023 · 2 comments

Comments

@lewisb42
Copy link

lewisb42 commented Feb 6, 2023

Please provide the following information:

  • Version of JMockit that was used: 1.49

  • Description of the problem or enhancement request:
    Per the Mock annotation documentation: "Alternatively, a single fake method having only the Invocation parameter will match all real methods of the same name, regardless of their parameters."

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.

  • Check the following:
  • If a defect or unexpected result, JMockit project members should be able to reproduce it.
    For that, include an example test (perhaps accompanied by a Maven/Gradle build script) which
    can be executed without changes and reproduces the failure.

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
		);
}

}
`

  • The JDK where the problem occurs is a final release, not a development build.
    JDK Info:
    openjdk version "17.0.5" 2022-10-18
    OpenJDK Runtime Environment Temurin-17.0.5+8 (build 17.0.5+8)
    OpenJDK 64-Bit Server VM Temurin-17.0.5+8 (build 17.0.5+8, mixed mode)
@cyqw
Copy link

cyqw commented Feb 13, 2023

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
Copy link
Author

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) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants