2015-04-30 4 views
7

Das Problem, das ich angetroffen habe, ist, wenn ich im then Block zu überprüfen, dass eine Ausnahme ausgelöst wurde, und dieser Aufruf auf einen Schein wurde gemacht.Spock Verifizieren einer Ausnahme durch Mock zusammen mit Scheininteraktion

Blick auf das Setup unter:

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() 
} 

Der obige Test mit der Meldung fehlschlägt: Expected exception java.lang.RuntimeException, but no exception was thrown, aber der Code den Mock Einrichtung explizit die Ausnahme auslöst.

Lustig genug, wenn Sie die letzte Zeile entfernen: 1 * a.a() der Test besteht. Ich hatte kein ähnliches Problem, wenn ich eine weitere Assertion im then-Block zusammenstellte, die keine Ausnahmen verifiziert.

Irgendwelche Ideen, was ist los?

+0

Während @ Opals Antwort richtig ist, würde ich fragen, warum das eine gute Idee ist. Im Allgemeinen (sicherlich nicht in allen Fällen, aber vielen) müssen Sie nur überprüfen, ob eine Interaktion stattfindet, wenn die betreffende Methode keinen direkten Einfluss auf den getesteten Code hat. Eine Methode, die einen Wert zurückgibt oder eine Ausnahme auslöst. –

+0

Der Code aus der Frage wurde von einem realen Fall inspiriert, in dem ich überprüfen wollte, ob eine Methode, die in eine Datenbank schreibt, aufgerufen wird, und wenn ein Fehler ausgelöst wird, wird er propagiert. Es könnte mehr Gründe für diese spezielle Ausnahme geben, also musste ich überprüfen, ob die Interaktion mit dem Mock der Grund dafür ist. – jarzeb

Antwort

10

Es sollte in der folgenden Art und Weise konfiguriert und überprüft werden:

@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() { 
    } 
} 

Wenn Sie beide Mock und überprüfen Wechselwirkungen Mock Verhalten in where/then Block konfiguriert werden soll.