Spock 模拟显示为 null
Spock mocks showing up as nulls
这是我的主要class:
@Slf4j
class ConsoleReaderWorker implements Runnable {
ConsoleReader reader
Writer writer
RemoteCommandSelector commandSelector
@Inject
ConsoleReaderWorker(ConsoleReader reader, Writer writer, RemoteCommandSelector commandSelector) {
super()
this.reader = reader
this.writer = writer
this.commandSelector = commandSelector
}
@Override
void run() {
try {
String line
while ((line = reader.readLine()) != null) {
commandSelector.select(line).execute(writer)
writer.flush()
}
} catch(InterruptedException ex) {
log.warn("${this} interrupted with: ${ExceptionUtils.getStackTrace(ex)}")
}
}
}
这是我对 Spock Specification
的尝试 class:
class ConsoleReaderWorkerSpec extends Specification {
def "when enter key is pressed then a command is selected and executed and the writer is flushed"() {
given: "a running fixture with some mock dependencies"
ConsoleReader reader = Mock(ConsoleReader)
Writer writer = Mock(Writer)
RemoteCommand command = Mock(RemoteCommand)
RemoteCommandSelector commandSelector = Mock(RemoteCommandSelector)
reader.readLine() >> '\n'
commandSelector.select(_) >> command
ConsoleReaderWorker worker = new ConsoleReaderWorker(reader, writer, commandSelector)
when: "the enter key is pressed"
worker.run()
then: "a command is executed"
1 * commandSelector.select(_)
}
}
本质上,我想确认当 run()
方法被调用时,commandSelector#select()
方法是用 any 参数调用的。
当我 运行 我得到:
java.lang.NullPointerException: Cannot invoke method execute() on null object
at com.nocbots.nbsvc.remote.cli.jline.ConsoleReaderWorker.run(ConsoleReaderWorker.groovy:33)
at com.nocbots.nbsvc.remote.cli.jline.ConsoleReaderWorkerSpec.when enter key is pressed then a command is selected and executed and the writer is flushed(ConsoleReaderWorkerSpec.groovy:25)
ConsoleReadyWorker
的第 33 行是对位于 while
循环内的 commandSelector.select()
的调用:
commandSelector.select(line).execute(writer)
关于为什么的任何想法?!?如您所见,我已将 commandSelector#select()
模拟连接到 return RemoteCommand
模拟,因此它永远不应该为空...想法?
尝试:
then: "a command is executed"
1 * commandSelector.select(_) >> command
而不是:
commandSelector.select(_) >> command
请看docs。当你同时模拟和验证时,应该使用 then
块。
编辑
这是您收到的与 spock 相关的错误,相信我。查看下面的 运行nable 脚本(可以 运行 使用 groovy 控制台):
@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
@Grab('cglib:cglib-nodep:3.1')
import spock.lang.*
class ConsoleReaderWorkerSpec extends Specification {
def "when enter key is pressed then a command is selected and executed and the writer is flushed"() {
given: "a running fixture with some mock dependencies"
ConsoleReader reader = Mock(ConsoleReader)
Writer writer = Mock(Writer)
RemoteCommand command = Mock(RemoteCommand)
RemoteCommandSelector commandSelector = Mock(RemoteCommandSelector)
reader.readLine() >> '\n'
ConsoleReaderWorker worker = new ConsoleReaderWorker(reader, writer, commandSelector)
when: "the enter key is pressed"
worker.run()
then: "a command is executed"
1 * commandSelector.select(_) >> command
}
}
class ConsoleReaderWorker implements Runnable {
ConsoleReader reader
Writer writer
RemoteCommandSelector commandSelector
ConsoleReaderWorker(ConsoleReader reader, Writer writer, RemoteCommandSelector commandSelector) {
this.reader = reader
this.writer = writer
this.commandSelector = commandSelector
}
@Override
void run() {
try {
String line
while ((line = reader.readLine()) != null) {
commandSelector.select(line).execute(writer)
writer.flush()
}
} catch(InterruptedException ex) {
log.warn("${this} interrupted with: ${ExceptionUtils.getStackTrace(ex)}")
}
}
}
class Writer {
void flush() {}
}
class RemoteCommand {
void execute(Writer w) {
}
}
class ConsoleReader {
String readLine() {
''
}
}
class RemoteCommandSelector {
RemoteCommand select(o) {
new RemoteCommand()
}
}
它失败了,因为 select
被调用了两次,但不会因 NPE 而失败。要修复它,请添加以下行:
reader.readLine() >>> ['\n', null]
这是我的主要class:
@Slf4j
class ConsoleReaderWorker implements Runnable {
ConsoleReader reader
Writer writer
RemoteCommandSelector commandSelector
@Inject
ConsoleReaderWorker(ConsoleReader reader, Writer writer, RemoteCommandSelector commandSelector) {
super()
this.reader = reader
this.writer = writer
this.commandSelector = commandSelector
}
@Override
void run() {
try {
String line
while ((line = reader.readLine()) != null) {
commandSelector.select(line).execute(writer)
writer.flush()
}
} catch(InterruptedException ex) {
log.warn("${this} interrupted with: ${ExceptionUtils.getStackTrace(ex)}")
}
}
}
这是我对 Spock Specification
的尝试 class:
class ConsoleReaderWorkerSpec extends Specification {
def "when enter key is pressed then a command is selected and executed and the writer is flushed"() {
given: "a running fixture with some mock dependencies"
ConsoleReader reader = Mock(ConsoleReader)
Writer writer = Mock(Writer)
RemoteCommand command = Mock(RemoteCommand)
RemoteCommandSelector commandSelector = Mock(RemoteCommandSelector)
reader.readLine() >> '\n'
commandSelector.select(_) >> command
ConsoleReaderWorker worker = new ConsoleReaderWorker(reader, writer, commandSelector)
when: "the enter key is pressed"
worker.run()
then: "a command is executed"
1 * commandSelector.select(_)
}
}
本质上,我想确认当 run()
方法被调用时,commandSelector#select()
方法是用 any 参数调用的。
当我 运行 我得到:
java.lang.NullPointerException: Cannot invoke method execute() on null object
at com.nocbots.nbsvc.remote.cli.jline.ConsoleReaderWorker.run(ConsoleReaderWorker.groovy:33)
at com.nocbots.nbsvc.remote.cli.jline.ConsoleReaderWorkerSpec.when enter key is pressed then a command is selected and executed and the writer is flushed(ConsoleReaderWorkerSpec.groovy:25)
ConsoleReadyWorker
的第 33 行是对位于 while
循环内的 commandSelector.select()
的调用:
commandSelector.select(line).execute(writer)
关于为什么的任何想法?!?如您所见,我已将 commandSelector#select()
模拟连接到 return RemoteCommand
模拟,因此它永远不应该为空...想法?
尝试:
then: "a command is executed"
1 * commandSelector.select(_) >> command
而不是:
commandSelector.select(_) >> command
请看docs。当你同时模拟和验证时,应该使用 then
块。
编辑
这是您收到的与 spock 相关的错误,相信我。查看下面的 运行nable 脚本(可以 运行 使用 groovy 控制台):
@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
@Grab('cglib:cglib-nodep:3.1')
import spock.lang.*
class ConsoleReaderWorkerSpec extends Specification {
def "when enter key is pressed then a command is selected and executed and the writer is flushed"() {
given: "a running fixture with some mock dependencies"
ConsoleReader reader = Mock(ConsoleReader)
Writer writer = Mock(Writer)
RemoteCommand command = Mock(RemoteCommand)
RemoteCommandSelector commandSelector = Mock(RemoteCommandSelector)
reader.readLine() >> '\n'
ConsoleReaderWorker worker = new ConsoleReaderWorker(reader, writer, commandSelector)
when: "the enter key is pressed"
worker.run()
then: "a command is executed"
1 * commandSelector.select(_) >> command
}
}
class ConsoleReaderWorker implements Runnable {
ConsoleReader reader
Writer writer
RemoteCommandSelector commandSelector
ConsoleReaderWorker(ConsoleReader reader, Writer writer, RemoteCommandSelector commandSelector) {
this.reader = reader
this.writer = writer
this.commandSelector = commandSelector
}
@Override
void run() {
try {
String line
while ((line = reader.readLine()) != null) {
commandSelector.select(line).execute(writer)
writer.flush()
}
} catch(InterruptedException ex) {
log.warn("${this} interrupted with: ${ExceptionUtils.getStackTrace(ex)}")
}
}
}
class Writer {
void flush() {}
}
class RemoteCommand {
void execute(Writer w) {
}
}
class ConsoleReader {
String readLine() {
''
}
}
class RemoteCommandSelector {
RemoteCommand select(o) {
new RemoteCommand()
}
}
它失败了,因为 select
被调用了两次,但不会因 NPE 而失败。要修复它,请添加以下行:
reader.readLine() >>> ['\n', null]