使用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中模拟此函数调用。
答案 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
}
}
如果你可以修改method2()以注入Config,那么你可以使用Groovy的MockFor。