不了解交互在 Spock 中的真正运作方式
Don't understand how interactions really work in Spock
Groovy 中有一个超级简单的 spock 测试用例!本规范文件中定义的所有 classes/interface。 (spock 中的规范文件只是一个测试用例文件)。
似乎无法理解工作流程。在测试用例工作流程中如何实例化、注入和销毁模拟对象?感谢任何帮助...
我遇到的特定问题是理解交互语句:1*mockURLAdapter.openConnection( ) 的工作原理。在我的理解中,这只是一个验证语句,断言方法 'openConnection(_)' 是用非空参数调用的。 How/Why 是否调用此断言导致方法 weatherService.run( ) 失败?返回的异常如代码所示...
import spock.lang.Specification
class WeatherServiceImpl {
private URLAdapter urlAdapter;
private URLConnection urlConn;
public WeatherServiceImpl(urlAdapter){
this.urlAdapter=urlAdapter
}
def run(city) {
urlConn=urlAdapter.openConnection(city)
return urlConn.getResponseCode()
}
}
interface URLAdapter {
def openConnection(city)
}
class WeatherServiceImplSpec extends Specification {
def mockURLAdapter = Mock(URLAdapter)
def mockURLConn = Mock(HttpURLConnection)
def weatherService=new WeatherServiceImpl(mockURLAdapter);
def "Need to figure out the effects of lines: 'troublesome' and 'weirdo' "() {
given:
mockURLConn.getResponseCode()>> 9999
mockURLAdapter.openConnection(_)>>mockURLConn;
when:
def result=weatherService.run("New York")
then:
// Uncommenting line 'troublesome' below throws a null-pointer exception:
// java.lang.NullPointerException: Cannot invoke method getResponseCode() on null object
// at WeatherServiceImpl.run(URLAdapterConnectionSpec.groovy:29)
// at WeatherServiceImplSpec.delivers events to all subscribers(URLAdapterConnectionSpec.groovy:54)
// Commenting out line 'troublesome' gives no issue!!
// Line 'troublesome':
// 1*mockURLAdapter.openConnection(_)
// Line 'weirdo':
// And yet, line 'weirdo' works just fine, commented or not!(i.e. test passes, no exception thrown)!!
1*mockURLAdapter.openConnection(_)>>mockURLConn;
//WTH is happening! ?
result==9999
}
}
你两次指定了 mockURLAdapter 应该 return 的内容,第二次你说不要 return 任何东西,当然它保留在你最后的决定中。
// Line 'troublesome':
1 * mockURLAdapter.openConnection(_)
这意味着调用 openConnection(_) 时不会 return 发生任何事情。如果你想指定交互,那么你应该把它放在 then: 子句中
正确的做法应该是这样的:
def "Need to figure out the effects of lines: 'troublesome' and 'weirdo' "() {
when:
def result=weatherService.run("New York")
then:
1 * mockURLAdapter.openConnection(_) >> mockURLConn;
1 * mockURLConn.getResponseCode() >> 9999
result == 9999
}
Groovy 中有一个超级简单的 spock 测试用例!本规范文件中定义的所有 classes/interface。 (spock 中的规范文件只是一个测试用例文件)。
似乎无法理解工作流程。在测试用例工作流程中如何实例化、注入和销毁模拟对象?感谢任何帮助...
我遇到的特定问题是理解交互语句:1*mockURLAdapter.openConnection( ) 的工作原理。在我的理解中,这只是一个验证语句,断言方法 'openConnection(_)' 是用非空参数调用的。 How/Why 是否调用此断言导致方法 weatherService.run( ) 失败?返回的异常如代码所示...
import spock.lang.Specification
class WeatherServiceImpl {
private URLAdapter urlAdapter;
private URLConnection urlConn;
public WeatherServiceImpl(urlAdapter){
this.urlAdapter=urlAdapter
}
def run(city) {
urlConn=urlAdapter.openConnection(city)
return urlConn.getResponseCode()
}
}
interface URLAdapter {
def openConnection(city)
}
class WeatherServiceImplSpec extends Specification {
def mockURLAdapter = Mock(URLAdapter)
def mockURLConn = Mock(HttpURLConnection)
def weatherService=new WeatherServiceImpl(mockURLAdapter);
def "Need to figure out the effects of lines: 'troublesome' and 'weirdo' "() {
given:
mockURLConn.getResponseCode()>> 9999
mockURLAdapter.openConnection(_)>>mockURLConn;
when:
def result=weatherService.run("New York")
then:
// Uncommenting line 'troublesome' below throws a null-pointer exception:
// java.lang.NullPointerException: Cannot invoke method getResponseCode() on null object
// at WeatherServiceImpl.run(URLAdapterConnectionSpec.groovy:29)
// at WeatherServiceImplSpec.delivers events to all subscribers(URLAdapterConnectionSpec.groovy:54)
// Commenting out line 'troublesome' gives no issue!!
// Line 'troublesome':
// 1*mockURLAdapter.openConnection(_)
// Line 'weirdo':
// And yet, line 'weirdo' works just fine, commented or not!(i.e. test passes, no exception thrown)!!
1*mockURLAdapter.openConnection(_)>>mockURLConn;
//WTH is happening! ?
result==9999
}
}
你两次指定了 mockURLAdapter 应该 return 的内容,第二次你说不要 return 任何东西,当然它保留在你最后的决定中。
// Line 'troublesome':
1 * mockURLAdapter.openConnection(_)
这意味着调用 openConnection(_) 时不会 return 发生任何事情。如果你想指定交互,那么你应该把它放在 then: 子句中
正确的做法应该是这样的:
def "Need to figure out the effects of lines: 'troublesome' and 'weirdo' "() {
when:
def result=weatherService.run("New York")
then:
1 * mockURLAdapter.openConnection(_) >> mockURLConn;
1 * mockURLConn.getResponseCode() >> 9999
result == 9999
}