2010-01-06 1 views
6

Ho un regolatore di Grails, che si basa sul taglib messaggio per risolvere un messaggio i18n:Come deridere/stub chiamate al messaggio taglib controller Grails

class TokenController { 
def passwordReset = { 
    def token = DatedToken.findById(params.id); 
    if (!isValidToken(token, params)) { 
     flash.message = message(code: "forgotPassword.reset.invalidToken") 
     redirect controller: 'forgotPassword', action: 'index' 
     return 
    } 
    render view:'/forgotPassword/reset', model: [token: token.token] 
} 
} 

Ho scritto un test di unità per il controller:

class TokenControllerTests extends ControllerUnitTestCase { 

void testPasswordResetInvalidTokenRedirect() { 

    controller.passwordReset() 
    assert... 
} 
} 

Dal momento che la taglib messaggio viene chiamato nel controller ottengo un MissingMethodException:

groovy.lang.MissingMethodException: No signature of method: TokenController.message() is applicable for argument types: (java.util.LinkedHashMap) values: [[code:forgotPassword.reset.invalidToken]]

Qualcuno conosce il modo migliore per aggirare questo problema in un test unitario? Idealmente vorrei esprimere delle affermazioni sul messaggio, ma al momento sarei felice se il test fosse appena iniziato!

Grazie

risposta

2

Oltre a provare le risposte di cui sopra, ho deciso di risolvere il messaggio in gsp e quindi rimuovere la dipendenza dal tag lib tutto insieme.

Il mio codice per la classe ora assomiglia a:

if (!isValidToken(token, params)) { 
    flash.message = "forgotPassword.reset.invalidToken" 

E nel SPG ho:

<g:message code="${flash.message}" args="${flash.args}" default="${flash.defaultMsg}"/> 

Una soluzione ispirata the grails docs

Di risposte Naturalmente Derek e Burt di lavorare per tutte le librerie di tag quindi sono soluzioni più generali.

+0

posso aggiungere questo al tuo codice: flash.args = [some, args] – Eldelshell

8

Si potrebbe aggiungere dinamicamente il metodo mancante nel test. Non sono sicuro se questa è corretta al 100%, ma qualcosa di simile ....

void testPasswordResetInvalidTokenRedirect() { 
    controller.metaClass.message = { LinkedHashMap arg1 -> return 'test message output'} 
    controller.passwordReset() 
    assert... 
} 
+0

Grazie Derek, che funziona a meraviglia. Nel frattempo ho cambiato il mio codice per risolvere il messaggio nella gsp in quanto sembrava molto più ordinario di farlo nel controller. –

+1

Quindi, se si fa questo, allora sarà eco-back il codice messaggio: 'myController.metaClass.message = {args LinkedHashMap -> ritorno "$ {} args.code"}' Ad esempio: 'vuoto testShow_NoSuch() { myController.params.id = 999 modello def = myController.show() assertNull modello assertEquals 'default.not.found.message', myController.flash.message }' –

5

È possibile cablare l'alto utilizzando il metaclasse, qualcosa come:

void testPasswordResetInvalidTokenRedirect() { 

    TokenControllerTests.metaClass.message = { Map p -> return "foo" } 
    controller.passwordReset() 
    assert... 
} 

Ciò restituisce lo stesso messaggio di sempre (supponendo non ti interessa davvero quale sia il valore) ma puoi aggiungere la logica se vuoi, cioè controlla il valore di 'codice' e restituisci una stringa corrispondente.

0

Credo che questo sia il modo migliore ...

Mettere questo nel test poco prima di chiamare il metodo di controllo:

controller.metaClass.message = { LinkedHashMap key -> assertEquals 'please.create.business', key.code}