Intellij call method: how to auto complete with all arguments?
For example: method foo
public class Foo {
public void doSomething(int name, int value, int somethingElse) {
...
}
}
In subclass Bar
public class Bar extends Foo {
#Override
public void doSomething(int name, int value, int somethingElse) {
super.doSomething(_);
}
}
calling superclass doSomething(..) method, its arguments are not auto completed, and i have to type in all arguments with the same names.
Same issue as calling methods of other classes. In eclipse, they will
be auto completed by best guess. How to achieve this in Intellij?
Use Code | Completion | SmartType Ctrl+Shift+Space:
Related
Here's the code. The code in method test and test2 are different because the parameter passed to Test constructor are different. Actually, if I change any parameter to null, intellij stops reporting the duplication. Is there any way to fix this?
---- Updated --------
I pass 2 functions doing totally different things but intellij still reports duplication
public class TestMain {
public void test(int a)
{
System.out.println("haha");
System.out.println("hahaa");
TestMain testMain = new TestMain();
new Test(testMain::test3);
System.out.println("hahaaa");
}
public void test2(int a)
{
System.out.println("haha");
System.out.println("hahaa");
TestMain testMain = new TestMain();
new Test(testMain::still_dup);
System.out.println("hahaaa");
}
public void test3(int a) {
System.out.println("abc");
}
public void still_dup(int a) {
String b = "edf";
b.toLowerCase();
}
public class Test {
Test(handler h) {
}
}
public interface handler<M> {
void entitySelector(int a);
}
public static void main(String[] args) {
TestMain test = new TestMain();
test.test(1);
System.out.println("-------");
test.test2(2);
}
}
I think the best way to fix this is to replace test and test2 by a single method. You don't have to distinguish what to pass the constructor because it's the current method. This might be the reason why code duplication is reported. The methods can be replaced by a single one without problems.
Let have these overloaded methods in a class:
class Test{
public void func1(int X , String s) {
// do something
}
public void func1(int X) {
// do something
}
public void func1(int X , int Y) {
// do something
}
what happen (what does the compiler do) when func1(2,3) from another class is called:
the compiler finds directly the thired version of func1 in class Test like calling non-overloaded methods or
like if-else statements, the entire overloaded methods with name func1 are tested to find which of them has the same set of arguments as func(2,3)
I searched in some documentations but couldn't find the answer.
Can anyone advise if it is possible to use an expectations/verifications to test that private methods are being called the-right-number-of-times/right-parameters.
The Class under test has been Mocked-Up - with one private method overridden.
Am Testing a public method which calls into a number of private methods.
I wish to know if it is possible to verify the calls to other private methods which will be called when the public method is being executed ?
Some idea of the code/class under test;
public class UnderTest {
public void methodPublic(arg 1){
.....
methodPrivate1(var1);
....
methodPrivate2(var2);
}
private void methodPrivate1(var1){
//do stuff
}
private void methodPrivate2(var1){
//do stuff
}
}
In my test case
#Test
public void stateBasedTestMethod()
{
UnderTest underTest;
new MockUp<UnderTest>() {
#Mock(invocations = 1)
private void methodPrivate2(var1) {
//do nothing in the mocked case
}
};
underTest = new UnderTest();
underTest.methodPublic(arg1);
new Verifications() {{
// Is there a way to test that methodPrivate1 has been called-once/with-expected-arguments
}};
}
Edited in response to the answer from Rogério.
I am using jmockit 1.12
and the Verifications is FAILING as the method using the provided solution is invoking the method twice as I thought from the JMockit documentation.
Failure Trace;
mockit.internal.UnexpectedInvocation: Expected exactly 1 invocation(s) of MyHelperTest$1#method3..., but was invoked 2 time(s)
Included is the full code I am using for this.
As described above - my goal is to mock one of the private methods to do nothing.
And ensure that I can verify that the other private method is called only once.
Thanks in advance and hopefully will get a better understanding if this is possible with Jmockit.
Test Code.
public class MyHelperTest {
#Test
public void testHelper(#Mocked final MyDependent myDependent) {
final MyHelper myHelper;
new MockUp<MyHelper>() {
#Mock(invocations = 1)
private void method3(MyDependent myTable) {
System.out.println("In Mocked Method");
//do nothing in the mocked case
}
};
myHelper = new MyHelper();
myHelper.method1(myDependent);
new Verifications() {{
invoke(myHelper, "method2", myDependent); times = 1;
}};
}
}
Class under test.
public class MyHelper {
public void method1(MyDependent myDependent){
method2(myDependent);
}
private void method2(MyDependent myDependent) {
myDependent.setValue(1);
method3(myDependent);
}
private void method3(MyDependent myDependent) {
myDependent.setValue(2);
}
}
Dependent Class
public class MyDependent {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
It's possible, though not recommended to mock private methods.
Using the Expectations API:
#Tested #Mocked MyHelper myHelper;
#Test
public void testHelper(#Mocked final MyDependent myDependent)
{
new NonStrictExpectations() {{ invoke(myHelper, "method3", myDependent); }};
myHelper.method1(myDependent);
new Verifications() {{ invoke(myHelper, "method2", myDependent); times = 1; }};
}
... where the invoke(...) method is statically imported from class mockit.Deencapsulation.
I noticed that if a method you want to verify is not mocked, when the static block in an Expectations or Verifications instance is executed that the code calls the method that you are trying to mark as expected or verify.
This might explain the extra invocation that you are seeing.
One suggestion: if you are already mocking the class with MockUp (and thus creating an anonymous subclass) so you can override the private method, why not change the access of the overridden private method to protected or public? Then you can create an expectation or verification on it.
You could also provide a public field "public int counter=0;" and have your overridden method increment the counter. Then you can use an assert on it after the test is complete.
I am currently applying AspectJ to our project, and I found a behavior which is a bit strange to me.
Q1:
I added a new constructor to my current class with inter-type declaration, and found that the class's member variable is not initialized if the new constructor is used to instantiate my class.
For example:
The class which I'll add a new constructor to:
public class Child {
public String name = "John";
public Child(String desc) {
// TODO Auto-generated constructor stub
}
}
The aspectJ code:
public aspect MyTest {
public Child.new(String desc, int num) {
System.out.println("Child Name:" + this.name);
}
}
If I instantiate the Child with the new constructor:
new Child("A child", 5)
the member variable this.name is not initialized as will be done with the original constructor.
But, if I call the original constructor:
new Child("A child")
the member variable this.name will be initialized to "John" as usual
The result:
Child Name:null
Is this a limitation of AspectJ? Is there anyway to resolve this issue?
I don't really want to add the code for member variable initialization to the new constructor.
Q2:
It seems in the newly added constructor, super.method() can not be correctly resolved.
The class which I'll add a new constructor to:
public class Child extends Parent{
public String name = "John";
public Child(String desc) {
}
}
Child extends Parent. Parent has a method init()
public class Parent {
public void init() {
//....
}
}
I add a new constructor for the Child in my aspect.
public aspect MyTest {
public Child.new(String desc, int num) {
super.init();
}
}
The above aspect code will trigger an exception.
Exception in thread "main" java.lang.NoSuchMethodError: com.test2.Child.ajc$superDispatch$com_test2_Child$init()V
at MyTest.ajc$postInterConstructor$MyTest$com_test2_Child(MyTest.aj:19)
at com.test2.Child.<init>(Child.java:1)
at MainProgram.main(MainProgram.java:11)
My workaround is to define another method for my class Child, and indirectly call the super.method() within that method
For example, add a new method that calls super.init() for Child
public void Child.initState()
{
super.init();
}
Now, I can call initState() in the newly added constructor like below:
public aspect MyTest {
public Child.new(String desc, int num) {
this.initState();
}
}
Is this a limitation of AspectJ? Is this the only way to resolve this issue?
Thank you all for your time :)
Foe the first questions, it seems that the lint warning will appear when compiling:
(unless you close the lint warning)
"inter-type constructor does not contain explicit constructor call: field initializers in the target type will not be executed [Xlint:noExplicitConstructorCall]"
Therefore I'd say it's an AspectJ's limitation.
The best way to do this might be call the other constructors of Child in the constructor added by AspectJ
For example:
public aspect MyTest {
public Child.new(String desc, int num) {
this("Hello"); // -> This will call the constructor of Child, and trigger fields initialization
System.out.println("Child Name:" + this.name);
}
}
For the second question, I think it's a bug of aspectJ.
That decompile the woven target byte code will find that the method “com.test2.Child.ajc$superDispatch$com_test2_Child$init()V” will be inserted. It implies this method should be generate by aspectJ, but there is no such method in the byte code.
The code for an ITD introduction is no different that the code that you would add to a class directly. So without member initialization code in your introduced constructor, members will , of course, remain uninitialized. So you need to change you code in Q1 as follows.
public Child.new(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Child Name:" + this.name);
}
As for Q2, it works fine for me.
class Parent {
public void init() {
System.out.println("P.init");
}
}
class Child extends Parent {
}
aspect Intro {
public void Child.init(){
super.init();
System.out.println("C.init");
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
c.init();
}
}
prints:
P.init
C.init
Changing the introduced method to something other than init works too (to match your code).
Regarding your comment: I fail to see what difference you have made in Q1. Sorry, I don't get it.
As for Q2 part of your comment, constructor arrangement works for me:
class Parent {
protected String name;
public Parent(String name) {
this.name = name;
}
}
class Child extends Parent {
int age;
public Child(String name) {
super(name);
}
}
aspect Intro {
public Child.new(String name, int age){
super(name);
this.age = age;
System.out.println("this.name: " + this.name + " this.age: " + this.age);
}
}
prints this.name: myname this.age: 2
I have multiple classes that have similar implementation for different named methods:
class MyClassX
{
public int MyClassXIntMethod(){}
public string MyClassXStringMethod(){}
}
class MyClassY
{
public int MyClassYIntMethod(){}
public string MyClassYStringMethod(){}
}
the methods inside the classes have similar implementation but because the method's names are different (due to 3rd party constraints) i cannot use inheritance.
I'm looking for an elegant solution that would be better than implementing the same functionality over and over again.
The classic answer IMHO is use the adpater pattern for every 3rd party calling party.
Don't apply blindly but see if it is a good fit first.
class MyClassXAdapter
{
IMyInterface _myImpClass
public int MyClassXIntMethod(){ return _myImpClass.IntMethod()}
public string MyClassXStringMethod(){ return _myImpClass.StringMethod() }
}
class MyClassYAdapter
{
IMyInterface _myImpClass
public int MyClassYIntMethod(){ return _myImpClass.IntMethod()}
public string MyClassYStringMethod(){ _myImpClass.StringMethod() }
}
class MyClassImplementation :IMyInterface
{
public int IntMethod(){}
public string StringMethod(){}
}
And whats the problem in using composition?
class MyClassY
{
private MyClassX myclx;
public int MyClassYIntMethod()
{
return myclx.MyClassXIntMethod();
}
public string MyClassYStringMethod(){...Similarly here...}
}
Why not simply create a common super class, and let each "MyClass_" call that common function? You can have a different program signature and still reuse the same codes pieces. Without copy and paste the same code again.
class MyClassX extends MyClassGeneric
{
public int MyClassXIntMethod(){}
public string MyClassXStringMethod(){}
}
class MyClassY extends MyClassGeneric
{
public int MyClassYIntMethod(){ return MyClassIntMethod();}
public string MyClassYStringMethod(){return MyClassStringMethod();}
}
class MyClassGeneric
{
protected int MyClassIntMethod(){ /*...... logic .....*/ return 0; }
protected string MyClassStringMethod(){/*...... logic ....*/return "";}
}
Real world example.
Without "software patternitis". (I apply software patterns, very useful, but, I'm not adicted to them).
collections.hpp
#define pointer void*
class Collection {
protected:
VIRTUAL bool isEmpty();
VIRTUAL void Clear();
}
class ArrayBasedCollection: public Collection {
protected:
int internalInsertFirst(pointer Item);
int internalInsertLast(pointer Item);
pointer internalExtractFirst(int Index);
pointer internalExtractLast(int Index);
}
class Stack: public ArrayBasedCollection {
public:
OVERLOADED bool isEmpty();
OVERLOADED void Clear();
// calls protected "internalInsertFirt"
void Push(pointer Item);
// calls protected "internalExtractLast"
pointer Pop(pointer Item);
}
class Queue: public ArrayBasedCollection {
public:
OVERLOADED bool isEmpty();
OVERLOADED void Clear();
// calls protected "internalInsertFirt"
void Push(pointer Item);
// calls protected "internalExtractFirst"
pointer Pop(pointer Item);
}
Cheers.