Spock 的多线程代码测试
Multithreading code testing by Spock
我想验证在我的 运行ning 线程之一中抛出的异常。这是我的一段测试代码:
then:
def e = thrown(RequestFormatException)
e.message == "Incorrect first line: INCORRECT LINE"
当我 运行 收到下一条消息时:
Exception in thread "Thread-1" by.westside.staircase.core.exception.RequestFormatException: Incorrect first line: INCORRECT LINE
at by.westside.staircase.core.util.HttpUtil.parseHttpRequest(HttpUtil.kt:19)
at by.westside.staircase.core.server.ServerThread.run(ServerThread.kt:26)
at java.lang.Thread.run(Thread.java:745)
Expected exception of type 'by.westside.staircase.core.exception.RequestFormatException', but no exception was thrown
at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
at by.westside.staircase.core.server.SyncServerSpec.should throw exception in incorrect first line case(SyncServerSpec.groovy:26)
thrown(RequestFormatException)
这应该在 then:
之后的第一行,因为这是 spock 施加的约束。
无论何时调用 thrown 或 notThrown 都应该是第一个语句。
注意: thrown
和 notThrown
都是 return true,因此也不应该有比较运算符。
因此,在您的情况下,应该如下所示:
then:
thrown(RequestFormatException)
Spock 和 JUnit 一样,只能断言从执行测试的线程抛出的异常,而不是 "any thread in the application"。您的异常未被 spock 捕获,无法断言。
您可以使用 Thread.uncaughtExceptionHandler
但您可能应该 unit-test 在您的线程中执行可运行对象 - 或者在您的业务逻辑中实现一些错误处理,并测试这部分代码。
我 运行 遇到了同样的问题,并采取了一条简单的、曲折的路线。本着 "good software is testable software" 的精神,我添加了一个标志并对其进行断言,并将其标记为://仅用于测试。当然,这会在以后被忽略。
我认为另一种选择是实际捕获测试用例中的异常并断言。这是我的代码片段(用 Groovy Spock 编写):
def exceptionThrown = false
def exceptionMessage
def thread = new Thread( {_ ->
try{
//code you are testing
} catch(Exception e) { // change this to the exception you want to catch
exceptionThrown = true
exceptionMessage = e.getMessage()
}
})
then: "the right exception should be thrown"
exceptionThrown
exceptionMessage = "I am thrown" //this should be your error message
我想验证在我的 运行ning 线程之一中抛出的异常。这是我的一段测试代码:
then:
def e = thrown(RequestFormatException)
e.message == "Incorrect first line: INCORRECT LINE"
当我 运行 收到下一条消息时:
Exception in thread "Thread-1" by.westside.staircase.core.exception.RequestFormatException: Incorrect first line: INCORRECT LINE
at by.westside.staircase.core.util.HttpUtil.parseHttpRequest(HttpUtil.kt:19)
at by.westside.staircase.core.server.ServerThread.run(ServerThread.kt:26)
at java.lang.Thread.run(Thread.java:745)
Expected exception of type 'by.westside.staircase.core.exception.RequestFormatException', but no exception was thrown
at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
at by.westside.staircase.core.server.SyncServerSpec.should throw exception in incorrect first line case(SyncServerSpec.groovy:26)
thrown(RequestFormatException)
这应该在 then:
之后的第一行,因为这是 spock 施加的约束。
无论何时调用 thrown 或 notThrown 都应该是第一个语句。
注意: thrown
和 notThrown
都是 return true,因此也不应该有比较运算符。
因此,在您的情况下,应该如下所示:
then:
thrown(RequestFormatException)
Spock 和 JUnit 一样,只能断言从执行测试的线程抛出的异常,而不是 "any thread in the application"。您的异常未被 spock 捕获,无法断言。
您可以使用 Thread.uncaughtExceptionHandler
但您可能应该 unit-test 在您的线程中执行可运行对象 - 或者在您的业务逻辑中实现一些错误处理,并测试这部分代码。
我 运行 遇到了同样的问题,并采取了一条简单的、曲折的路线。本着 "good software is testable software" 的精神,我添加了一个标志并对其进行断言,并将其标记为://仅用于测试。当然,这会在以后被忽略。
我认为另一种选择是实际捕获测试用例中的异常并断言。这是我的代码片段(用 Groovy Spock 编写):
def exceptionThrown = false
def exceptionMessage
def thread = new Thread( {_ ->
try{
//code you are testing
} catch(Exception e) { // change this to the exception you want to catch
exceptionThrown = true
exceptionMessage = e.getMessage()
}
})
then: "the right exception should be thrown"
exceptionThrown
exceptionMessage = "I am thrown" //this should be your error message