2014-01-09 4 views
4

The specs2 Matchers guide состояние:Как мне сопоставить сообщение об исключении Exception?

throwA[ExceptionType](message = "boom") дополнительно проверяет, если сообщение исключения, как и ожидалось

Но когда я использую это, сообщение, по-видимому соответствует на всю StackTrace вместо только сообщения об исключении.

Тест

"cont'd what if -- running test again shows that the app has already died" in { 
    running(new FakeApplication(additionalConfiguration = inLocalPostgresDatabase())) { 
    db2 withSession { 
     val comboboxOpsClass = new ComboboxOps(database) 
    } 
    } must throwA[SQLException](message = "Attempting to obtain a connection from a pool that has already been shutdown") 
} 

StackTrace

[error]  'Attempting to obtain a connection from a pool that has already been shutdown. 
[error]  Stack trace of location where pool was shutdown follows: 
[error]  java.lang.Thread.getStackTrace(Thread.java:1568) 
[error]  com.jolbox.bonecp.BoneCP.captureStackTrace(BoneCP.java:572) 
[error]  com.jolbox.bonecp.BoneCP.shutdown(BoneCP.java:161) 

много много больше линий

[error]  org.specs2.execute.ResultExecution$class.execute(ResultExecution.scala:22) 
[error]  org.specs2.execute.ResultExecution$.execute(ResultExecution.scala:116) 
[error]  org.specs2.specification.FragmentExecution$class.executeBody(FragmentExecution.scala:28) 
[error]  
[error]  sbt.ForkMain$Run.runTestSafe(ForkMain.java:211) 
[error]  sbt.ForkMain$Run.runTests(ForkMain.java:187) 
[error]  sbt.ForkMain$Run.run(ForkMain.java:251) 
[error]  sbt.ForkMain.main(ForkMain.java:97) 
[error]  ' doesn't match '.*Attempting to obtain a connection from a pool that has already been shutdown.*' (FakeApplicationSpec.scala:138) 

Может кто-нибудь мне точку на рабочий пример этого использования specs2?

ответ

5

Ненавижу говорить об этом, но я не нашел общий способ узнать, что текст был другим, кроме как позволить ему произойти и добавить его после факта ... или перейти к источнику исключения и скопировать его из там. Вот что я сделал в Novus-JDBC, строка 91:

"handle when take more than it can give" in{ 
    val iter0 = nonCounter() 

    val iter = iter0 slice (0,10) 

    (iter next() must be greaterThan 0) and 
    (iter next() must be greaterThan 0) and 
    (iter next() must be equalTo -1) and 
    (iter next() must be equalTo 3) and 
    (iter.hasNext must beFalse) and 
    (iter next() must throwA(new NoSuchElementException("next on empty iterator"))) 
} 
+1

Я думаю, что я просто заметил ошибку в моем тестовом модуле, поставив это здесь. Должны быть 'iter' и' iter0' в первых двух 'next() должны быть более длинными 0' совпадениями. – wheaties

0

Каркас метание трассировки стека «захваченный» в сообщении строки, вместо того, чтобы просто начинку исключение где-то и бросание его позже.

Испытательный стенд ищет s".*$message.*".r, который не будет работать без режима DOTALL (который позволяет «Точку» матч, он же новой строки режима однострочный):

scala> val text = """abc 
    | def 
    | ghi 
    | jkl""" 
text: String = 
abc 
def 
ghi 
jkl 

scala> val r = ".*def.*".r 
r: scala.util.matching.Regex = .*def.* 

scala> import PartialFunction._ 
import PartialFunction._ 

scala> cond(text) { case r() => true } 
res0: Boolean = false 

scala> val r2 = "(?s).*def.*".r 
r2: scala.util.matching.Regex = (?s).*def.* 

scala> cond(text) { case r2() => true } 
res1: Boolean = true 

Если вы тестируете для просто префикс текста, вы можете сделать это путем добавления встроенного DOTALL (?s), т.е. message = "boom(?s)":

scala> val r3 = ".*abc(?s).*".r 
r3: scala.util.matching.Regex = .*abc(?s).* 

scala> cond(text) { case r3() => true } 
res2: Boolean = true 

Но пытаться проверить что-либо на последующей строке подведет:

scala> val r4 = ".*(?s)def.*".r 
r4: scala.util.matching.Regex = .*(?s)def.* 

scala> cond(text) { case r4() => true } 
res3: Boolean = false 

Якоря Aweigh будет работать, если тест рамка сделала это:

scala> val r5 = ".*def.*".r.unanchored 
r5: scala.util.matching.UnanchoredRegex = .*def.* 

scala> cond(text) { case r5() => true } 
res4: Boolean = true 
+0

Видимо, этот? https://github.com/etorreborre/specs2/pull/483 –

1

Вы хотите иметь возможность сопоставления с сообщением исключения, если вы реализуете исключение как случай класс и включает это сообщение в своем первом списке параметров конструктора.

case class ObjectionException(statement: String) 
extends Exception(statement) 

try throw ObjectionException("I object") 
catch { 
    case ObjectionException("I object") => println("I objected to myself?") 
    case ObjectionException("You object") => println("I don't care!") 
    case ObjectionException(objection) => println(s"Objection: $objection") 
} 

// Exiting paste mode, now interpreting. 

I objected to myself? 
defined class ObjectionException 

scala> 

Вы также можете использовать Regex, чтобы соответствовать сообщение:

val ContentObjection = ".*Content.*".r 

try throw ObjectionException("ObjectionableContent") 
catch { 
    case ObjectionException(ContentObjection()) => println("Questionable Content") 
    case ObjectionException(objection)   => println(s"Objection: $objection") 
} 

// Exiting paste mode, now interpreting. 

Questionable Content 
ContentObjection: scala.util.matching.Regex = .*Content.* 
Смежные вопросы