2015-08-19 146 views
1

使用Spock框架进行java单元测试。 当单元测试方法方法1()和方法1被调用的方法方法2(),在方法2(),其具有如下代码语句:嘲笑函数调用

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])注释的单元测试,以限制类元注射改变你的测试用例。

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' 

由于方法2()没有得到一个配置实例注入其中,模拟的功能出了问题。因此,我们将在类级别使用Groovy的metaClass(因为出于同样的原因,实例级别也不存在)。您可以覆盖Config.getProps()这样的:

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

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

所以,你可以大致写你斯波克测试是这样的:

// 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

如果你可以修改方法2()要注入Config,那么您可以使用Groovy的MockFor,这样会更好。