2015-04-30 20 views
7

Il problema che ho riscontrato è quando provo a verificare nel blocco then che è stata generata un'eccezione e che è stata effettuata una chiamata su una simulazione.Spock che verifica un'eccezione generata da simulazione con interazione simulata

Guardate il programma di installazione di seguito:

class B { 
    def b(A a) { 
     a.a() 
    } 
} 

class A { 
    def a() { 
    } 
} 

def "foo"() { 
    given: 
    def a = Mock(A) 
    a.a() >> { throw new RuntimeException() } 
    B b = new B() 

    when: 
    b.b(a) 

    then: 
    thrown(RuntimeException) 
    1 * a.a() 
} 

Il test precedente non riesce con il messaggio: Expected exception java.lang.RuntimeException, but no exception was thrown, ma l'impostazione del finto codice genera esplicitamente l'eccezione.

Abbastanza divertente, se si rimuove l'ultima riga: 1 * a.a() passa il test. Non ho avuto problemi simili nel mettere insieme altre affermazioni nel blocco allora che non verificano le eccezioni.

Qualche idea cosa sta succedendo?

+0

Mentre la risposta di @ Opal è corretta mi chiederei perché questa è una buona idea. Generalmente (certamente non in tutti i casi, ma in molti casi) è sufficiente verificare che si verifichi un'interazione quando il metodo in questione non ha alcun effetto diretto sul codice in prova. Un metodo che restituisce un valore o genera un'eccezione. –

+0

Il codice della domanda è stato ispirato da un caso reale in cui volevo verificare che venga chiamato un metodo di scrittura su un database e, se viene generato un errore, viene propagato. Potrebbero esserci più motivi per quella particolare eccezione, quindi ho dovuto verificare che l'interazione con il mock ne sia la ragione. – jarzeb

risposta

10

Esso dovrebbe essere configurato e verificato nel seguente modo:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
@Grab('cglib:cglib-nodep:3.1') 

import spock.lang.* 

class Test extends Specification { 
    def "foo"() { 
     given: 
     def a = Mock(A) 
     B b = new B() 

     when: 
     b.b(a) 

     then: 
     thrown(RuntimeException) 
     1 * a.a() >> { throw new RuntimeException() } 
    } 
} 


class B { 
    def b(A a) { 
     a.a() 
    } 
} 

class A { 
    def a() { 
    } 
} 

Se si sia finto e verificare le interazioni comportamento finta dovrebbe essere configurata in where/then blocco.