当前位置: 首页 > 知识库问答 >
问题:

Spock测试绿色,尽管应用程序代码抛出异常

鲜于光赫
2023-03-14

我使用Groovy和Gradle进行测试。

我的应用程序代码中有以下几行:

Platform.runLater( new Runnable() {
    void run() {
    ....

        FileChooser fc = getFileChooser()
        File file = fc.showOpenDialog( null )

        // if( file != null && file.exists() ) { <--- this is what I have to put
        if( file.exists() ) { 
            println( "file $file exists")
            analyseFile( file )
        }

如果我模拟(使用groovymock,因为javafx.stage.filechooserfinal),以便fc.showopendialog返回null,我希望在file.exists()nullpointerexception.一个是。

但这并没有出现在测试结果中,测试结果都是绿色的。发现这种情况的唯一方法是查看该类的测试结果:然后您会看到显示“stderr”的灰色按钮。

这似乎是因为包络runnable正在“吞噬”它...

Spock中有什么方法可以使runnable中的异常导致测试失败吗?

def "getting a null result from the showOpenDialog should be handled OK"(){
    given:
    FileChooser fc = GroovyMock( FileChooser )
    ConsoleHandler ch = Spy( ConsoleHandler ){ getFileChooser() >> fc }
    ch.setMaxLoopCount 10
    systemInMock.provideLines( "o" )
    fc.showOpenDialog( _ ) >> null

    when:
    com.sun.javafx.application.PlatformImpl.startup( {} )
    ch.loop()
    Thread.sleep( 1000L ) // NB I know this is a rubbish way to handle things... but I'm a newb with Spock!

    then:
    0 * ch.analyseFile( _ )
}
class ConsoleHandler {
    int loopCount = 0
    def maxLoopCount = Integer.MAX_VALUE - 1
    def response
    FileChooser fileChooser = new FileChooser()

    void analyseFile( File file ) {
        // ...
    }
    void loop() {
        while( ! endConditionMet() ){
            print '> '
            response = System.in.newReader().readLine()
            if( response ) response = response.toLowerCase()
            if( response == 'h' || response == 'help' ){
                println "Help: enter h for this help, q to quit"
            }
            else if ( response == 'o' ){
                Platform.runLater( new Runnable() {
                    void run() {
                        FileChooser fc = getFileChooser()
                        File file = fc.showOpenDialog( null )
                        // if( file != null && file.exists() ) {
                        if( file.exists() ) {
                            analyseFile( file )
                        }
                    }
                })
            }
        }
    }
    boolean endConditionMet() {
        loopCount++
        response == 'q' || loopCount > maxLoopCount
    }
    static void main( args ) {
        com.sun.javafx.application.PlatformImpl.startup( {} )
        new ConsoleHandler().loop()
        com.sun.javafx.application.PlatformImpl.exit()
    }
}

另一个可能需要解释的东西是Spock测试代码中的SysteminMock,它允许测试向应用程序代码中的stdin提供文本:

import org.junit.contrib.java.lang.system.TextFromStandardInputStream
import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.emptyStandardInputStream
....
// field of the Test class, of course:
@Rule
public TextFromStandardInputStream systemInMock = emptyStandardInputStream()

my GradleDependencies子句中的对应行是:

testCompile 'com.github.stefanbirkner:system-rules:1.16.0'

...但我认为这可以通过在Groovy测试文件中使用@grab来获得,对吗?

共有1个答案

方长卿
2023-03-14

这是我认为唯一可行的前进方向:像这样改变这一点:

else if ( response == 'o' ){
    Platform.runLater(new Runnable() {
        void run() {
            openFileChooser()
        }
    })
}

ConsoleHandler的新方法:

def openFileChooser() {
    FileChooser fc = getFileChooser()
    File file = fc.showOpenDialog( null )
    // if( file != null && file.exists() ) {
    if( file.exists() ) {
        analyseFile( file )
    }
}

新斯波克测试:

def "getting a null result from the showOpenDialog should be handled OK2"(){
    given:
    FileChooser fc = GroovyMock( FileChooser )
    ConsoleHandler ch = Spy( ConsoleHandler ){ getFileChooser() >> fc }
    fc.showOpenDialog( _ ) >> null

    when:
    com.sun.javafx.application.PlatformImpl.startup( {} )
    ch.openFileChooser()
    Thread.sleep( 1000L )

    then:
    0 * ch.analyseFile( _ )
}
 类似资料:
  • 我用Spock测试Java代码。我测试这段代码: 我写了一个测试: 它失败是因为抛出了另一个CustomException。但是在块中,我捕获这个异常并抛出一个,因此我希望我的方法将抛出,而不是。如何测试它?

  • 我正在尝试测试当试图除以零时,是否会抛出带有定制消息的异常。 方法是这样的: 在搜索了一些解决方案后,我发现这是一种做这件事的方法,但是我的IDE不能识别“expected”... 我只是不知道为什么我的 IDE 无法识别“预期”。不知道这是否与 Junit 版本有关,或者我使用的语法是否存在问题。 在我迄今为止使用的所有其他测试中,我从未在@Test之后添加任何内容。我刚刚在另一个线程中找到了类

  • 我已经使用spock对我的java项目进行了一段时间的单元测试,但遇到了一个问题。我有一个实用程序方法可以从http请求中获取参数,如果http请求为null并且正在尝试使用spock测试它,则可以获取空字符串。我的测试如下所示: 但是,当我运行这个测试时,我得到以下错误: 在做了一些研究之后,我明白了在给定的块之前运行的块,因此出现了错误,但是我只是想知道是否有一个变通方法? 我知道要使用测试之

  • 我在StackOverflow中搜索了相同类型的问题,并检查了每个响应,但仍然面临这个问题。我正在测试从名为readStream()的方法抛出的IOException,该方法确实抛出了IOException,但Junit使用AssertionException使测试失败。 下面是我的单元测试: 如您所见,我已经尝试让原始类中的异常实际抛出异常,而不是仅仅捕获并打印堆栈跟踪: 我还尝试使用注释@te

  • 注意:如果我不使用JMockit,我可以进行调试,但是在生产代码中测试方法需要使用这个方法。 关于如何让调试器从使用JMockit的Spock测试中停在Java代码中,有什么想法吗?

  • 除了统一的HTML或XML报告之外,我如何获得Spock测试执行控制台输出或类似于我的应用程序日志? 使用Gradle2.11和Log4j支持的Slf4j。