Почему я обязан использовать GroovyMock в этом случае? - PullRequest
0 голосов
/ 20 марта 2020

Вот MCVE:

main. groovy:

package core

import javafx.application.Application
import javafx.stage.Stage
import javafx.fxml.FXMLLoader

class App extends Application {
    FXMLLoader fxmlLoader = new FXMLLoader()
    static App instance
    FXMLController fxmlController
    void start(Stage primaryStage) {
        instance = this
        fxmlLoader.load( getClass().getResource("mainWindow.fxml").openStream() )
        primaryStage.show()
    }
}
class FXMLController {}

testfx. groovy:

package core

import javafx.fxml.FXMLLoader
import javafx.scene.Node
import javafx.stage.Stage
import org.testfx.framework.spock.ApplicationSpec

class FirstFXSpec extends ApplicationSpec {
    void start(Stage stage)  { }
    def 'at start, fxmlLoader should load mainWindow.fxml'() {
        given:
        App.instance = new App()
        App.instance.fxmlLoader = Mock(FXMLLoader) {
            getController() >> Mock(FXMLController)
        }
        Node mockNode = Mock(Node)
        // Stage mockStage = GroovyMock( Stage ){
        Stage mockStage = Mock( Stage ){

            show() >> null
        }

        when:
        App.instance.start( mockStage )

        then:
        true // details of test omitted
    }
}

build.gradle:

plugins {
    id 'groovy'
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories { mavenCentral() }
javafx {
    version = '11.0.2'
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}
dependencies {
    implementation 'org.codehaus.groovy:groovy:2.5.+'
    testImplementation 'junit:junit:4.12'
    testImplementation 'org.spockframework:spock-core:1.3-groovy-2.5'
    testImplementation 'net.bytebuddy:byte-buddy:1.9.3'
    testImplementation 'org.objenesis:objenesis:2.6'
    testImplementation 'org.testfx:testfx-spock:4.0.15-alpha'
}
application {
    mainClassName = 'core.App'
}

Сведения о файле src / main / resources / core / mainWindow.f xml не важны, но вот пример:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="600.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/11.0.1"
      xmlns:fx="http://javafx.com/fxml/1" fx:controller="core.FXMLController" >
    <children>
        <Label text="Some label"></Label>
    </children>
</VBox>

Вышеприведенный тест не пройден. Реальный метод Stage.show() вызывается, и тот факт, что это макет, игнорируется.
Если я изменяю его с Mock на GroovyMock, вместо этого используется метод макета show(), и тест проходит.
Почему обычный Спок Mock игнорируется?

1 Ответ

2 голосов
/ 20 марта 2020

Обычный Java Mock s не может издеваться над конечными методами и согласно JavaDocs Stage.show является окончательным. GroovyMock s работают с использованием groovy MOP и, следовательно, работают только при вызове из кода groovy, но в этом отношении они более мощные.

...