Javafx 在这种情况下,为什么我必须使用GroovyMock?
这是一个MCVE: main.groovy:Javafx 在这种情况下,为什么我必须使用GroovyMock?,javafx,groovy,mocking,spock,testfx,Javafx,Groovy,Mocking,Spock,Testfx,这是一个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 FXMLControlle
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 {}
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
}
}
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'
}
testfx.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 {}
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
}
}
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'
}
build.gradle:
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 {}
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
}
}
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.fxml的详细信息并不重要,但下面是一个示例:
<?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
则使用Mock方法show()
,测试通过。为什么一个普通的Spock
Mock
会被忽略?普通JavaMock
s不能模拟final方法,根据阶段。show
是finalGroovyMock
s通过使用groovy MOP工作,因此只有在从groovy代码调用时才能工作,但在这方面它们更强大。普通JavaMock
s不能模拟最终方法,根据阶段。show
是最终的GroovyMock
s通过使用groovy MOP工作,因此只有在从groovy代码调用时才能工作,但它们在这方面更强大。Duh!因为它是最终版本
。谈论一个“小学生的错误”。。。谢谢!;-)我只是想写同样的答案,因为昨天晚上我很忙。我在OP的测试中添加了这一行以进行说明:println“modifiers=“+java.lang.reflect.Modifier.toString(Stage.getDeclaredMethod(“show”).modifiers)
。输出将是:modifiers=public final
.Duh!因为它是最终版本
。谈论一个“小学生的错误”。。。谢谢!;-)我只是想写同样的答案,因为昨天晚上我很忙。我在OP的测试中添加了这一行以进行说明:println“modifiers=“+java.lang.reflect.Modifier.toString(Stage.getDeclaredMethod(“show”).modifiers)
。输出为:modifiers=public final
。