Issue
I'm creating a custom Matcher for running Espresso tests on a 3rd party ToggleSwitch. I want for Espresso to know which toggle is "selected" in these switches.
Android Studio is underlining in red part of the custom matcher class. The catch is, the project builds successfully and the test runs successfully.
I can't figure out
Why the Ambiguous Method Call Error is showing up
If there's a syntax error, why the build is successful.
Here is the code
import android.view.View;
import com.llollox.androidtoggleswitch.widgets.ToggleSwitch;
import org.hamcrest.Description;
import androidx.test.espresso.matcher.BoundedMatcher;
public class ToggleSwitchMatcher extends BoundedMatcher<View, ToggleSwitch> {
private final int togglePos;
static ToggleSwitchMatcher inPosition(int togglePos){
return new ToggleSwitchMatcher(togglePos);
}
private ToggleSwitchMatcher(final int togglePos){
super(ToggleSwitch.class);
this.togglePos = togglePos;
}
@Override
protected boolean matchesSafely(ToggleSwitch item) {
return item.getCheckedPosition() == togglePos;
}
@Override
public void describeMismatch(Object item, Description description) {
super.describeMismatch(item, description);
}
@Override
public String toString() {
return super.toString();
}
@Override
public void describeTo(Description description) {
description.appendText("with checked position:").appendValue(togglePos);
}
}
The parenthesis in this line are underlined
return item.getCheckedPosition() == togglePos;
And the error states:
Ambiguous Method Call. Both getCheckedPosition() in ToggleSwitch and getCheckedPosition() in ToggleSwitch match
Solution
The error lies in the ToggleSwitch class. The class declares the property var checkedPosition : Int? = null
, for which Kotlin will generate a getter and a setter with the names getCheckedPosition
and setCheckedPosition
. However, the class also declares functions with these names.
Let's examine the Kotlin bytecode to see why it compiles. The property compiles to:
public final getCheckedPosition()Ljava/lang/Integer;
@Lorg/jetbrains/annotations/Nullable;() // invisible
L0
LINENUMBER 12 L0
ALOAD 0
GETFIELD com/llollox/androidtoggleswitch/widgets/ToggleSwitch.checkedPosition : Ljava/lang/Integer;
ARETURN
L1
LOCALVARIABLE this Lcom/llollox/androidtoggleswitch/widgets/ToggleSwitch; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
While the getter compiles to:
public final getCheckedPosition()I
L0
LINENUMBER 43 L0
ALOAD 0
GETFIELD com/llollox/androidtoggleswitch/widgets/ToggleSwitch.checkedPosition : Ljava/lang/Integer;
DUP
IFNULL L1
INVOKEVIRTUAL java/lang/Integer.intValue ()I
GOTO L2
L1
POP
ICONST_M1
L2
IRETURN
L3
LOCALVARIABLE this Lcom/llollox/androidtoggleswitch/widgets/ToggleSwitch; L0 L3 0
MAXSTACK = 2
MAXLOCALS = 1
The method signatures differ because of the return types, so the JVM accepts both methods, but to the caller it's ambiguous.
The class should instead move the getter and setter functionality to the get()
and set()
declarations of the property.
Answered By - fejd
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.