Próbuję testów jednostkowych z ramą Play w scala. Pisałem klasę, która sprawdza, czy konfiguracja jest poprawna (Mam obsługi błędu nieco więcej, ale ja faktycznie użyć tego kodu do mojego testu teraz):Testy weryfikacyjne Mockito scala nie działają (gra w ramy)
class TaskQueueConfig(conf: Configuration) {
val schedulingEnabled = conf.getBoolean("schedulingEnabled").get
val processingEnabled = conf.getBoolean("processingEnabled").get
val queueName = conf.getString("queue").get
}
Jestem testowania to za pomocą odtwarzać 2.1. 1 w konfiguracji domyślnej Test:
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")
}
}
}
dostaję następujący błąd:
[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)
jest to bardzo dziwne, ponieważ kod jest bardzo odizolowany i nie ma wyraźnie tylko 1 conf .getString call w TaskQueueConfig. Linia 10 to linia z metodą getString. Linia 61 to linia z "był jeden (tQConf) .getString"
Jak mogę rozwiązać ten problem?
(nie ma różnicy między byłem i był).
PS: Wiem, że ten przykład jest dość bezużyteczny do testowania, ale mam bardziej złożone konfiguracje, w których istnieją pewne reguły, które należy przetestować.
Sposób aktualizacji 1 getString ma dwa parametry, drugi parametr ma wartość domyślną brak (to typ jest wariant [Zestaw [String]]). Kiedy jawnie dodaję None do konfiguracji i weryfikacji, to nadal nie działa. Ale kiedy dodaję null
zamiast tego, działam.
val tqConf = mock[Configuration]
tqConf.getString("queue", null) returns Some("queueName")
tqConf.getBoolean("schedulingEnabled") returns Some(true)
tqConf.getBoolean("processingEnabled") returns Some(true)
val c = new TaskQueueConfig(tqConf)
there was one(tqConf).getString("queue", null)
there was one(tqConf).getString(any[String], any[Option[Set[String]]])
there were two(tqConf).getBoolean(any[String])
there was one(tqConf).getBoolean("schedulingEnabled")
there was one(tqConf).getBoolean("processingEnabled")
c.processingEnabled must beTrue
c.schedulingEnabled must beTrue
c.queueName must be("queueName")
Sądzę więc, że teraz pytanie brzmi: dlaczego muszę używać wartości NULL?
Czemu weryfikacji co nazwano na pozornie configs vs tylko sprawdzenie stanu końcowy utworzonego obiektu? Jeśli zgasłeś poprawnie, powinieneś po prostu sprawdzić, czy wartości właściwości 'TaskQueueConfig' odpowiadają ustawionym wartościom skrótowym. Wiem, że to nie odpowiada na twoje pytanie, ale z pewnością wyeliminowałoby to ten problem ... – cmbaxter
W tym konkretnym przypadku, oczywiście, ale pochodzę z większego przykładu, w którym to miałem, i zawęziłem to do najmniejszy możliwy przykład, więc proszę, zostańcie ze mną! – Jaap
Moje dwie wstępne przemyślenia dotyczyły tego, że policzono samą krępę (co spowodowało, że były to dwa połączenia) lub miałeś problem z określeniem zakresu i kolejna sekwencja testów również była zliczana, a więc dodatkowe wywołanie funkcji 'getString'.Sam przetestowałem pierwszą teorię i nie wygląda mi to tak, jakby mockito przypadkowo obejmowało upieranie się w liczbie połączeń. Jeśli chodzi o problem z zakresu, jeśli twój prawdziwy kod jest taki, jaki jest tutaj, a sztuczka nie jest tworzona globalnie, to nie powinno to być problemem. – cmbaxter