【问题标题】:How to test overloaded method using spock "where" table如何使用 spock“where”表测试重载方法
【发布时间】:2019-10-08 02:51:25
【问题描述】:

我想测试将null 传递给这些重载方法:

public static Object someMethod(String n) { /* some impl */ }
public static Object someMethod(Integer n) { /* some impl */ }

我试过了:

def "test someMethod"() {
    expect:
    someMethod(input) == expected
    where:
    input           | expected
    null as String  | someValue
    null as Integer | someValue
}

但我得到了错误:

groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method com.foo.MyClass#someMethod.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:  
    [class java.lang.String]  
    [class java.lang.Integer]

如何使用一种 spock 方法在 where 块中输入空值(使用其他值)来测试这些?

【问题讨论】:

  • 不知道有没有用。在 where 部分尝试定义闭包:{ someMethod(null as String) } | someValue 和期望部分 input()==expected
  • 我试图用 Spock 1.3 和 Groovy 2.5.8 重现您的问题,但不能。相反,我遇到了另一个 Spock 问题,请参阅 here。您必须使用其他版本的 Spock 和/或 Groovy。

标签: groovy null spock


【解决方案1】:

在这种情况下,类型转换不会被 Spock 继承,也不能被 Spock 继承。 但是您可以手动使用PojoWrapper,这就是Groovy 在内部表示类型转换的null

import org.codehaus.groovy.runtime.wrappers.PojoWrapper

def "test someMethod"() {
    expect:
    someMethod(input) == expected
    where:
    input                          | expected
    new PojoWrapper(null, String)  | someValue
    new PojoWrapper(null, Integer) | someValue
}

一个重要的注意事项是,第一组输入必须包含包装器,否则 Groovy 会优化 someMethod 调用,而不会解包参数。

所以这会起作用:

import org.codehaus.groovy.runtime.wrappers.PojoWrapper

def "test someMethod"() {
    expect:
    someMethod(input) == expected
    where:
    input                          | expected
    new PojoWrapper(null, Integer) | someValue
    0                              | someValue
}

虽然这不起作用但抛出ClassCastException:

import org.codehaus.groovy.runtime.wrappers.PojoWrapper

def "test someMethod"() {
    expect:
    someMethod(input) == expected
    where:
    input                          | expected
    0                              | someValue
    new PojoWrapper(null, Integer) | someValue
}

【讨论】:

    【解决方案2】:

    我试图用 Spock 1.3 和 Groovy 2.5.8 重现您的问题,但不能。相反,我遇到了另一个 Spock 问题,请参阅 here。您必须使用其他版本的 Spock 和/或 Groovy。

    无论如何,我刚刚链接到的 Spock 错误的一种解决方法是不要从 then:expect: 块中调用带有 null 参数的方法,而是从 when: 调用该方法,稍后在 @987654325 中进行比较@ 堵塞。另请参阅我的代码示例。

    除此之外,您需要将您的功能方法拆分为两种方法,一种用于您要测试的每种类型的null 对象。

    正在测试的 Java 类:

    package de.scrum_master.stackoverflow.q58279620;
    
    public class ClassUnderTest {
      public static Object someMethod(String n) {
        return n == null ? "nothing" : "something";
      }
    
      public static Object someMethod(Integer n) {
        return n == null ? -999 : 11;
      }
    }
    

    Spock 测试解决方法:

    package de.scrum_master.stackoverflow.q58279620
    
    
    import spock.lang.Specification
    import spock.lang.Unroll
    
    class PassingNullToOverloadedMethodTest extends Specification {
      @Unroll
      def "someMethod('#input') returns #expected"() {
        when:
        def result = ClassUnderTest.someMethod(input as String)
    
        then:
        result == expected
    
        where:
        input | expected
        "foo" | "something"
        ""    | "something"
        null  | "nothing"
      }
    
      @Unroll
      def "someMethod(#input) returns #expected"() {
        when:
        def result = ClassUnderTest.someMethod(input as Integer)
    
        then:
        result == expected
    
        where:
        input | expected
        0     | 11
        123   | 11
        null  | -999
      }
    }
    

    【讨论】:

    • 这是正确的方法:隔离测试。甚至重载的方法也代表不同的测试单元。
    • 解决方法实际上并不能回答问题;它提供了解决问题的方法。您的“解决方法”实际上完全回避了这个问题,使其与如何针对 where 块中给定混合类型的特定重载的核心问题无关。引用问题:如何使用 one spock 方法测试这些。如果可以证明我的问题没有解决方案,我会接受一种解决方法,但 IIRC 我自己解决了它 - 我明天将检查我的代码库以在 10 月左右提交,以尝试找到我所做的并将其发布为如果我找到了答案。
    • 如何证明这一点?也许通过数学证明? Spock 手册没有告诉您如何操作,整个 Internet 上都找不到相关的示例代码,一位经验丰富的 Spock 用户说他知道没有其他方法是不够的,显然。您应该专注于以干净的方式编写好的测试,这就是我通过使用两种特性方法来测试两种不同的对象方法所提供的。你为什么坚持人为的解决方案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 2017-06-29
    • 2021-10-24
    • 1970-01-01
    • 2014-05-07
    相关资源
    最近更新 更多