2012-04-18 4 views
19

Sto scrivendo un test per methodA() in una classe di servizio simile a quella indicata di seguito.Grails: Come faccio a prendere in giro altri metodi di una classe in prova che potrebbe essere chiamata internamente durante i test

Class SampleService { 
    def methodA(){ 
    methodB() 
    } 

    def methodB(){ 
    } 
} 

quando i test Methoda(), ho bisogno di essere in grado di prendere in giro la chiamata a MethodB() durante il test Methoda(). Sto usando la versione 2.0.x di Grails. Nelle distribuzioni 1.3.x, vorrei scrivere un mock sé come questo

def sampleServiceMock = mockFor(SampleService) 
sampleServiceMock.demand.methodB { -> } 

Ma questo non funziona nelle versioni 2.0.x. Mi chiedevo quali sono gli altri modi di deridere il metodo B() durante il test methodA()

+0

Qualcuno sa come farlo per Grails 3.2.8 con Spock? – nbkhope

risposta

34

Per questo tipo di problema che in realtà evitare schernisce e utilizzare la capacità built-in groovyProxy per lanciare una mappa di chiusure come un oggetto proxy. Questo vi dà l'esempio con alcuni Metodi sostituiti, ma altri passa attraverso la vera classe:

class SampleService { 
    def methodA() { 
     methodB() 
    } 

    def methodB() { 
     return "real method" 
    } 
} 

def mock = [methodB: {-> return "mock!" }] as SampleService 

assert "mock!" == mock.methodA() 
assert "real method" == new SampleService().methodA() 

Mi piace che cambia solo un esempio, può essere fatto in una sola riga, e non pasticciare con la metaclasse di qualsiasi cosa al di fuori di quell'istanza che deve essere ripulita.

+1

Sì, questo sembra un ottimo modo di prendere in giro i comportamenti. Mi manca ancora la capacità di autoironicarmi usando Grails 'mockFor() :( –

+0

Questo ha risolto i miei graal testando guai, grazie mille! – EdgeCaseBerg

+0

Brillante. Questo mi ha aiutato così come il test che ho fatto è stato creare chiusure Spock e non è stato in grado di affermare i valori effettivi restituiti dal controller (quando si prende in giro una chiamata di servizio). –

12

Ci sono molte alternative di derisione con Groovy. È possibile vedere alcuni documenti di Groovy Mocks, using Maps and Expandos instead of Mocks o using Closures instead of Mocks.

Nel tuo esempio, userò le funzionalità di metaprogrammazione di Groovy.

void testMethodA() { 
    service = new SampleService() 
    service.metaClass.methodB = { -> return "what you want" } 
    service.methodA() 
    assert "your condition" 
} 
+2

Finalmente ho usato questo approccio per deridere. Ma, semanticamente parlando, cambiare la firma di una classe per fare un passaggio di prova sembra estremo :) –

+0

E il metacass cambia le perdite anche in altri test. –

+0

I collegamenti (Groovy Mocks, utilizzando Maps e Expandos invece di Mock o usando Closures anziché Mocks) non funzionano più, correggili o cancellali. Grazie. – GSAN

Problemi correlati