Java 为什么在模拟TextView时会出现InvalidUseofMatcherException?

Java 为什么在模拟TextView时会出现InvalidUseofMatcherException?,java,android,unit-testing,textview,mockito,Java,Android,Unit Testing,Textview,Mockito,我有一组测试来验证我们Android应用程序中的一些功能。部分代码负责将某些字符串放入某些TextView。所以我想创建模拟TextView对象,以便在测试时使用: public static TextView getMockTextView() { TextView view = mock(TextView.class); final MutableObject<CharSequence> text = new MutableObject<CharSequen

我有一组测试来验证我们Android应用程序中的一些功能。部分代码负责将某些字符串放入某些TextView。所以我想创建模拟TextView对象,以便在测试时使用:

public static TextView getMockTextView() {
    TextView view = mock(TextView.class);
    final MutableObject<CharSequence> text = new MutableObject<CharSequence>();
    doAnswer(new Answer() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            text.value = (CharSequence) invocation.getArguments()[0];
            return null;
        }
    }).when(view).setText((CharSequence) any());
    when(view.getText()).thenReturn(text.value);
    return view;
}
我试过(
CharSequence)any()
(CharSequence)anyObject()
,甚至是
anyString()
eq(“”)
,只是想看看它是否有效,Mockito仍然不喜欢我尝试告诉它在
setText()
的单参数版本中该怎么做

有什么想法吗?

来自:

公共最终void setText(字符序列文本)

莫基托;Mockito生成的mock/spy类实际上是一个代理,但由于
setText(CharSequence)
是final,因此JVM假设它知道调用哪个实现(TextView的真正实现),并且不参考代理(Mockito实现),因为虚拟方法调度将指示它。大概
setText(CharSequence)
的实现实际上调用了
setText(CharSequence,BufferType)
,Mockito假设这是您想要模拟的调用,因此它会给您错误消息“预期2个匹配器,1个已记录”。(第二个匹配器将用于BufferType。)

您需要执行以下操作之一:

  • 使用,它使用一个特殊的类加载器在测试中用可用的等价物替换Android类
  • 使用,它还使用一个特殊的类加载器重写被测系统,以便即使在调用final方法时也将其委托给mock(以及许多其他添加的特性)
  • 完全跳过使用模拟,使用真实对象或编写完全可模拟的包装层

我已经回答了这个问题,但我不能100%肯定我的答案是正确的。如果没有,你能回答这个问题来澄清你的答案中的第49行是哪一行吗?谢谢你的回答!这个错误消息确实需要一些帮助:)这个特殊的例子我是通过做doAnswer(…)来工作的。当(view).setText((CharSequence)anyVararg(),(BufferType)anyVararg())…我想anyVararg()既包括了单参数的情况,也包括了双参数的情况。重要的部分不是
anyVararg()
,而是你在模仿;最好模拟
setText(any(CharSequence.class)、any(BufferType.class))
。请小心,它仍然非常脆弱,因为您依赖的假设是
setText(CharSequence)
调用
setText(CharSequence,BufferType)
并且没有做很多其他事情,在一个实现中您无法控制。是的。(如果异常只告诉我错误是什么,我会节省一半的时间:)
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
-> at com.me.util.MockViewHelper.getMockTextView(MockViewHelper.java:49)

This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));

For more info see javadoc for Matchers class.