2016-01-23 263 views
0

我想验证抛出我的一个运行线程的异常。这是一段我的测试代码:Spock的多线程代码测试

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) 
+0

你能想出一个我们可以尝试的例子吗? –

+0

@tim_yates你可以在任何由新Thread创建的线程中抛出异常(new RunnableClass())。start() – Cortwave

+0

为什么不测试runnable而不是一个线程你还没有引用 –

回答

1

斯波克一样,JUnit的,只能在执行测试,而不是“任何应用程序中的线程”从线程抛出的异常断言。你的异常不会被spock捕获,并且不能被声明。

你可以玩Thread.uncaughtExceptionHandler,但你应该单元测试在你的线程中执行的runnable,或者在业务逻辑中实现一些错误处理,然后测试这部分代码。

0

抛出(RequestFormatException)

这应该是你的第一线在then:之后,因为这是spock强加的限制。

每当抛出或不抛出它应该是第一个语句。

注意:thrownnotThrown都返回true,因此也不应该有比较运算符。

因此,在你的情况下,它应该是象下面这样:

then: 
thrown(RequestFormatException) 
0

我遇到了同样的问题,并采取了一个简单的Hokey路线。本着“优秀的软件是可测试的软件”的精神,我添加了一个标志并声明,标注它://仅用于测试。当然,这将被忽略。

0

我认为另一种选择是在您的测试用例中实际捕获异常并在其中声明。这里是我的代码片段(用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