首页 > 解决方案 > 如何使用 spock“where”表测试重载方法

问题描述

我想测试传递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块中的输入空值(使用其他值)来测试这些?

标签: groovynullspock

解决方案


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

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

除此之外,您需要将功能方法拆分为两种方法,一种用于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
  }
}

推荐阅读