jeudi 28 janvier 2016

Spock mocks showing up as nulls

Here is my main 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)}")
        }
    }
}

Here is my attempt at a Spock Specification for that 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(_)
    }
}

Essentially, I want to confirm that when the run() method is invoked, that the commandSelector#seclect() method is invoked with any argument.

When I run this I get:

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)

Line 33 of ConsoleReadyWorker is the call to commandSelector.select() that lives inside the while loop:

commandSelector.select(line).execute(writer)

Any ideas as to why?!? As you can see, I've wired commandSelector#select() mock to return the RemoteCommand mock, so it should never be null...ideas?

Aucun commentaire:

Enregistrer un commentaire