2013-09-05 4 views
8

Ich probiere Unit Tests mit Play Framework in scala aus. ich eine Klasse geschrieben habe, der überprüft, ob die Konfiguration korrekt ist (ich habe ein bisschen mehr Fehlerbehandlung, aber ich tatsächlich diesen Code für meinen Test verwenden jetzt):Mockito scala Überprüfungstests funktionieren nicht (play framework)

class TaskQueueConfig(conf: Configuration) { 
    val schedulingEnabled = conf.getBoolean("schedulingEnabled").get 
    val processingEnabled = conf.getBoolean("processingEnabled").get 
    val queueName = conf.getString("queue").get 
} 

Ich teste diese 2.1 spielen mit. Standardtestaufbau der 1:

class ConfigTestSpec extends Specification with Mockito with CalledMatchers { 
    "TaskQueueConfig" should { 
    "verify calls" in { 
     val tqConf = mock[Configuration] 
     tqConf.getString("queue") returns Some("queueName") 
     tqConf.getBoolean("schedulingEnabled") returns Some(true) 
     tqConf.getBoolean("processingEnabled") returns Some(true) 
     Logger.error("setup done") 

     val config = new TaskQueueConfig(tqConf) 

     there was one(tqConf).getString("queue") 
     there were two(tqConf).getBoolean(any[String]) 
     there were one(tqConf).getBoolean("schedulingEnabled") 
     there were one(tqConf).getBoolean("processingEnabled") 
    } 
    } 
} 

ich die folgende Fehlermeldung erhalten:

[error] x verify calls 
[error] The mock was not called as expected: 
[error] configuration.getString$default$2(); 
[error] Wanted 1 time: 
[error] -> at config.ConfigTestSpec$$anonfun$2$$anonfun$apply$4$$anonfun$apply$12.apply(ConfigTestSpec.scala:61) 
[error] But was 2 times. Undesired invocation: 
[error] -> at config.TaskQueueConfig.<init>(TaskQueueConfig.scala:10) (ConfigTestSpec.scala:61) 

das ist sehr seltsam, weil der Code sehr isoliert ist, und es ist klar, nur 1 conf .getString-Aufruf in TaskQueueConfig. Zeile 10 ist die Zeile mit der getString-Methode. Zeile 61 ist die Zeile mit "es gab einen (tQConf) .getString"

Wie kann ich dieses Problem beheben?

(es gibt keinen Unterschied zwischen waren und war).

PS: Ich weiß, dieses Beispiel ist ziemlich nutzlos zu testen, aber ich habe komplexere Konfigurationen, wo es einige Regeln gibt, die getestet werden müssen.

UPDATE 1 Die getString Methode zwei Parameter hat, der zweite Parameter einen Standardwert von keiner hat (es ist Typ ist Option [Set [String]]). Wenn ich die None explizit zur Einrichtung und Überprüfung hinzufüge, funktioniert sie immer noch nicht. Aber wenn ich stattdessen null hinzufüge, bekomme ich es funktioniert.

Also ich denke, die Frage ist jetzt, warum muss ich null verwenden?

+0

Warum Verifizieren Sie, was auf den Mock configs genannt wurde Verifizieren vs nur den Endstatus des erzeugten Objekts? Wenn Sie korrekt stubben, sollten Sie nur überprüfen, ob die Eigenschaftswerte von 'TaskQueueConfig' mit den von Ihnen eingerichteten Stub-Werten übereinstimmen. Ich weiß, dass dies Ihre Frage nicht beantwortet, aber es würde sicherlich dieses Problem für Sie beseitigen ... – cmbaxter

+0

In diesem speziellen Fall natürlich, aber ich komme aus einem größeren Beispiel, wo ich das hatte, und ich verengte es auf das kleinstmögliche Beispiel, also bitte bitte mit mir! – Jaap

+0

Meine beiden ersten Gedanken waren, dass entweder das Stubbing selbst gezählt wurde (also zwei Aufrufe) oder dass Sie ein Scoping-Problem hatten und eine weitere Testsequenz gezählt wurde, also der zusätzliche Aufruf von "getString".Ich habe die erste Theorie selbst getestet und es sieht nicht so aus, als ob Mockito versehentlich das Stubbing in die Call-Counts einbezieht. Wenn Ihr realer Code so ist, wie er hier ist, und der Mock nicht global erstellt wird, dann sollte das kein Problem sein. – cmbaxter

Antwort

4

Sie haben null im zweiargumentigen getString() Aufruf zu verwenden, da Mockito Sie entweder erfordert den Einsatz Matcher für alle Argumente oder gar keine verwenden.

So Mischen "queue" (ein Literal) mit any[Option[Set[String]]] (ein Matcher) wird nicht funktionieren. Manchmal Mockito kann aus arbeiten, dass Sie das getan haben und es gibt Ihnen ein Fehler, aber es scheint, wie Sie hier Pech haben ...

Versuchen Matcher in allen Positionen wie folgt aus:

tqConf.getString(org.mockito.Matchers.eq("queue"), any[Option[Set[String]]]) returns Some("queueName") 

und Verifizieren:

there was one(tqConf).getString(eq("queue"), any[Option[Set[String]]]) 
+0

Danke! Ich habe eine andere verwandte Frage dazu, können Sie erklären, warum tqConf.getString ("queue", None) gibt zurück Einige ("queueName") funktioniert nicht? Wenn ich das tue, erhalte ich eine NPE in dem Code, der getString ("queue") ruft. Get None ist der Standardwert für getString zweiten optionalen Parameter ... – Jaap

+1

Ich denke, Sie haben tatsächlich eine wirklich interessante getroffen Eckfall für Mockito Matcher vs Scala Standardargumente. Ich habe die Kombinationen getestet, und die einzigen, die funktionieren, sind: 'tqConf.getString (" queue ") gibt Some (" queueName ")' (dh direkt mit genau einem Literal, wobei das Standardarg vollständig ignoriert wird) und 'tqConf zurück .getString (org.mockito.Matchers.eq ("queue"), alle [Option [Set [String]]]) gibt Some ("queueName") 'zurück (dh die Verwendung von Matcher für _both_ Argumente wie die Mockito-Empfehlung). Ich würde immer noch die zweite Form bevorzugen, um explizit zu sein, aber es ist interessant ... – millhouse