Utilizzando Mockito con Specs2, eseguo servizi di simulazione per verificare le loro chiamate di metodo.
Il mio controller è istanziato da Spring. Ciò mi consente di considerare che è come class
anziché object
. => Questo è essenziale per rendere testabile controller
. Ecco un esempio:
@Controller
class MyController @Autowired()(val myServices: MyServices) extends Controller
Per abilitare Primavera per i controller, è necessario definire un oggetto Global
, come il gioco! documentazione spiega:
object Global extends GlobalSettings {
val context = new ClassPathXmlApplicationContext("application-context.xml")
override def getControllerInstance[A](controllerClass: Class[A]): A = {
context.getBean(controllerClass)
}
}
Il mio test di unità non ha bisogno di Spring; Ho appena passato i collaboratori (mock) al costruttore.
Tuttavia, per quanto riguarda il modello renderizzato, eseguo solo il test del tipo di risultato (Ok, BadRequest, Reindirizzamento ecc ...). Infatti, ho notato che non è affatto semplice fare il mio test per scansionare l'intero modello renderizzato nei dettagli (parametri inviati ad esso ecc.), Con solo test delle unità.
Quindi, per affermare che il modello giusto viene chiamato con gli argomenti giusti, mi fido dei miei test di accettazione che eseguono Selenium, o un possibile test funzionale, se preferisci, per cercare l'intero risultato previsto.
2 - I valori di ritorno dai servizi vengono passati al corretto attributi del modello
E 'abbastanza facile da controllare per vedere that..How? Affidandoti al compilatore! Preferisci passare alcuni tipi personalizzati al tuo modello invece di semplici primitivi, per esempio: phone: String
diventerebbe: phone: Phone
. (un oggetto di valore semplice). Pertanto, non c'è paura di passare gli attributi in un ordine non previsto al modello (nel test di unità o nel codice di produzione reale). Il compilatore in effetti avviserà.
Ecco un esempio di uno dei miei test di unità (semplificato) utilizzando le specifiche2: (Si noterà l'uso di un wrapper: WithFreshMocks
). Questo case class
consentirebbe di aggiornare tutte le variabili (mock in questo caso) test dopo il test. Quindi un buon modo per resettare i mock.
class MyControllerSpec extends Specification with Mockito {
def is =
"listAllCars should retrieve all cars" ! WithFreshMocks().listAllCarsShouldRetrieveAllCars
case class WithFreshMocks() {
val myServicesMock = mock[MyServices]
val myController = new MyController(myServicesMock)
def listAllCarsShouldRetrieveAllCars = {
val FakeGetRequest = FakeRequest() //fakeRequest needed by controller
mockListAllCarsAsReturningSomeCars()
val result = myController.listAllCars(FakeGetRequest).asInstanceOf[PlainResult] //passing fakeRequest to simulate a true request
assertOkResult(result).
and(there was one(myServicesMock).listAllCars()) //verify that there is one and only one call of listAllCars. If listAllCars would take any parameters that you expected to be called, you could have precise them.
}
private def mockListAllCarsAsReturningSomeCars() {
myServicesMock.listAllCars() returns List[Cars](Car("ferrari"), Car("porsche"))
}
private def assertOkResult(result: PlainResult) = result.header.status must_== 200
}
Perché non utilizzare ScalaCheck/ScalaTest/Specs2 .0? – 4lex1v
In particolare, come si crea un test utilizzando specs2.0 per intercettare la chiamata al servizio e la chiamata al modello? Gli esempi che ho potuto vedere testano l'applicazione nel suo complesso (integrata) –