2012-04-23 1 views
7

Ho una classe di dominio che estende una classe astratta che inietta il servizio spring security core plugin.Come simulare un servizio immesso in una classe di dominio da una classe di test del controller?

class Extra extends WithOwner { 
    String name 
} 

abstract class WithOwner { 
    transient springSecurityService 
    User user 

    def getCurrentUser() { 
     return springSecurityService.currentUser 
    } 

    def beforeValidate() { 
     if(!user) { 
      user = getCurrentUser() 
     } 
    } 

    Boolean isLoggedUserTheOwner(){ 
     return (user?.id == getCurrentUser()?.id) 
    } 
} 

Voglio implementare un test del controller.

@TestFor(ExtraController) 
@Mock([Extra, User, UserRole, Role]) 
class ExtraControllerTests { 

    void testEdit() { 
     def utils = new TestUtils() 
     def user1 = utils.saveUser1() 

     populateValidParams(params) 
     def extra = new Extra(params) 
     extra.user = user1 
     assert extra.save() != null 

     params.id = extra.id 


     def model = controller.edit() // Line 69 
     assert model.extraInstance == extra 
    } 
} 

Se eseguo la prova di cui sopra ottengo:

test-app ExtraController.testEdit --unit --echoOut | Esecuzione di 1 test dell'unità ... 1 di 1 - Uscita da testEdit-- | Errore: testEdit (com.softamo.movilrural.ExtraControllerTests) | java.lang.NullPointerException: impossibile ottenere la proprietà 'currentUser' su oggetto nullo su com.softamo.movilrural.WithOwner.getCurrentUser (WithOwner.groovy: 8) su com.softamo.movilrural.WithOwner.isLoggedUserTheOwner (WithOwner.groovy: 18) in com.softamo.movilrural.ExtraController.edit (ExtraController.groovy: 39) in com.softamo.movilrural.ExtraControllerTests.testEdit (ExtraControllerTests.groovy: 69) | Completato test di 1 unità, 1 fallito in 853ms

ho cercato senza successo di prendere in giro il servizio di sicurezza in questo modo:

Extra.metaClass.springSecurityService = new MockSpringSecurityService(user1) 

o addirittura beffardo il metodo

Extra.metaClass.getCurrentUser = { return user1 } 

Qualsiasi idea di come potrei aggirare questo problema.

+0

Ciao! Sono bloccato con lo stesso problema. Hai trovato una soluzione per la tua domanda? O forse hai un passaggio laterale per iniettare un servizio all'interno di un oggetto dominio senza auto-test autowiring? – snowindy

+0

Qualsiasi problema con questo problema ?, con lo stesso problema. –

risposta

1

Questo dovrebbe funzionare:

controller.springSecurityService = new SpringSecurityService() 

Se si vuole prendere in giro il metodo GetCurrentUser in questo servizio:

controller.springSecurityService.metaClass.getCurrentUser = { -> return user1 } 

io non sono sicuro se si può ommit -> in una riga sopra, in modo da testare esso. Se si desidera cancellare questo metodo preso in giro dopo l'uso o prima di un altro banco di prova utilizzare questo:

controller.springSecutiryService.metaClass = null 
+1

Questo spiega come iniettare il servizio nel controller, la sua domanda è come prendere in giro il servizio in un oggetto dominio. –

+0

Solo per il record, puoi omettere il '->' e semplificarlo con 'getCurrentUser = {user1}' –

2

Grails 2.x supporta la definizione di fagioli di primavera per gli ambienti di test che utilizzano la chiusura 'defineBeans'. Supporta l'integrazione delle dipendenze nei controller ecc. Non sono sicuro che funzioni anche per gli oggetti dominio. In teoria dovrebbe essere coerente tra gli oggetti/controller/servizi di dominio

Vedere http://grails.org/doc/latest/guide/single.html#testing - La sezione "Test dei semi di primavera".

+0

Ho provato a farlo ma non funziona. Non ho idea di come configurarlo per le classi di dominio.defineBeans { springSecurityService (new MockSpringSecurityService (user1)) } –

+0

Non è necessario eseguire un nuovo MockSpringSecurityService() quando si definisce un bean spring, solo springSecurityService (MockSpringSecurityService) –