嘲笑函数调用

时间:2015-08-19 07:15:28

标签: unit-testing groovy spock

使用Spock框架进行Java单元测试。 当单元测试方法method1()和method1调用方法method2()时,在method2()中有一个代码语句如下:

Config config = new Config();  
TimeZone tz=TimeZone.getTimeZone(config.getProps().getProperty(Constants.SERVER_TIMEZONE));

致电config.getProps().getProperty(Constants.SERVER_TIMEZONE)

返回America/Cambridge_Bay

在getProps方法中,属性文件是从weblogic域获取的,它在spcok中不可用,它的获取路径为null。

请建议如何在spock中模拟此函数调用。

2 个答案:

答案 0 :(得分:0)

我们可以使用元类注入来模拟给定块的单元测试中的响应方法2。这里ClassName是method2所属的类。

ClassName.metaClass.method2 = { inputParameters ->
        return "America/Cambridge_Bay"
    }

同样建议在单元测试中使用@ConfineMetaClass([ClassName])注释将元类注入更改限制在测试用例中。

答案 1 :(得分:0)

让我们从一个模拟你情况的例子开始:

class Config {
    Properties getProps() {
        def props = new Properties()

        props.setProperty(Constants.SERVER_TIMEZONE, 'America/Cambridge_Bay')
        props
    }
}

class Constants {
    static String SERVER_TIMEZONE = 'TIMEZONE'
}

Config config = new Config()

def timeZoneID = config.getProps().getProperty(Constants.SERVER_TIMEZONE)
def tz = TimeZone.getTimeZone(timeZoneID)
assert tz.ID == 'America/Cambridge_Bay'

由于method2()没有将 Config 实例注入其中,因此模拟是不可能的。所以我们将在类级别使用Groovy的metaClass(因为实例级别也是不可能的,出于同样的原因)。您可以像这样覆盖 Config.getProps()

Config.metaClass.getProps {
    def props = new Properties()

    props.setProperty(Constants.SERVER_TIMEZONE, 'Etc/UTC')
    props
}

所以你可以像这样编写你的Spock测试:

// import Constants
// import Config class

class FooSpec extends Specification {

  @ConfineMetaClassChanges
  def "test stuff"() {
    when:
    Config.metaClass.getProps {
        def props = new Properties()

        props.setProperty(Constants.SERVER_TIMEZONE, 'America/Cambridge_Bay')
        props
    }

    // Do more stuff

    then:
    // Check results
  }  
}

PS

如果你可以修改method2()以注入Config,那么你可以使用Groovy的MockFor。