【问题标题】:How to verify that specific class method was passed as parameter?如何验证特定的类方法是否作为参数传递?
【发布时间】:2016-11-09 12:17:21
【问题描述】:

在我测试的 MyClass 类中,我有:

public void execute(){
    service.call(ThisClass::method1);
}

以下:

void method1(){do 1;}
void method2(){do 2;}

在测试中:

@Mock
Service service;

@Test
public void testCallMethod1()
{
     MyClass myClass = new MyClass();
     myClass.execute();

     service.verify(any(Runnable.class));
}

它有效,但是,我如何验证该参数而不是任何 Runnable 是 method1 而不是 method2?

我正在寻找看起来像的解决方案(例如,不是真的有效):

service.verify(eq(MyClass::method1.getRunnable()))

【问题讨论】:

  • how do I specify that parameter was ... 是什么意思如果你想知道调用了哪个方法,这可能不是最好的实现
  • 代替那个,抱歉我的英语不好,编辑问题以澄清。
  • 好的,这只是为了测试目的...错过了那部分。测试这个有点奇怪,因为结果很重要,实现它的方法有点难以检查。 method#() 没有任何更新,我怀疑有办法。
  • 可以说函数几乎是一等公民,但是为它们创建的函数式接口实现具有未指定的相等性。同样,值类型在未来的版本中可能会成为一等公民,但它们的装箱表示的对象身份将是未指定的。 Integer.valueOf(0xcafebabe) == Integer.valueOf(0xcafebabe) 的结果也未指定。这并不意味着Integer 对象不是一等公民……
  • 您不能在Runnable 上拨打run 并验证它是否具有预期的效果?然后你正在测试一个结果而不是一个实现细节

标签: java unit-testing java-8 mockito


【解决方案1】:

以下对我有用:

public class MyTest {

public static class X{
    static void method1() {};
    static void method2() {};
}

@Test
public void throwAway() {
  ExecutorService service = mock(ExecutorService.class);
  Runnable command1 = X::method1;
  Runnable command2 = X::method2;
  service.execute(command1);
  verify(service).execute(command1);
  verify(service, never()).execute(command2);
}

}

关键是提取方法引用 lambda 并在执行和验证中使用它。否则,每个 "::" 运算符都会生成一个不同的 lambda 实例,它不适用于相等性测试,因为上面的一些 cmets 讨论了 lambda 相等性的语义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-24
    • 2017-05-18
    • 2012-07-18
    • 2015-01-22
    • 2021-05-02
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多