2012-02-03 5 views
12

Uso un bundle di messaggi in uno dei miei servizi in un progetto Grails 2.0 per testo internazionalizzato. Il caso d'uso è un oggetto di posta elettronica che viene inviato tramite il plug-in di posta in modo asincrono, quindi non ha senso avere questo in un controller o TagLib (dato il solito argomento di non accedere al testo o alle viste in un servizio). Questo codice funziona perfettamente con la mia app Grails in esecuzione, ma non sono sicuro di come testarlo.Come utilizzare l'unit test o l'integrazione di messageSource per i18n nel servizio Grails 2.0

Ho provato un PluginAwareResourceBundleMessageSource nei miei defineBeans in quanto è ciò che la mia applicazione in esecuzione inietta, ma ha portato a nullpointers in quanto sembra abbia bisogno di un po 'di setup intorno ai gestori di plugin e in modo tale che il mio ambiente di test non dia (anche integrazione) .

Ho quindi provato un ReloadableResourceBundleMessageSource come fosse puro Spring, ma non può sembrare di vedere i miei file .properties e non riesce con un messaggio No trovato sotto il codice 'my.email.subject' per le impostazioni locali 'en'.

Mi sento come se stessi scendendo un wormhole un po 'mentre accedere a Grails i18n in un servizio non è documentato nei documenti Grails, quindi se c'è un modo preferito per farlo, fammi sapere.

Nota Il file .properties si trova nella posizione standard grails-app/i18n.

Il test

@TestFor(EmailHelperService) 
class EmailHelperServiceTests { 

    void testSubjectsDefaultLocale() { 
     defineBeans { 
      //messageSource(PluginAwareResourceBundleMessageSource); Leads to nullpointers 
      messageSource(ReloadableResourceBundleMessageSource); 

     } 
     String expected = "My Expected subject Passed1 Passed2"; 
     String actual = service.getEmailSubjectForStandardMustGiveGiftFromBusiness(Locale.ENGLISH, Passed1 Passed2); 
     assertEquals("email subject", expected, actual); 

} 

Servizio:

class EmailHelperService { 
    def messageSource; 

    public String getEmailSubject(Locale locale, String param1, String param2) { 
     Object[] params = [param1, param2].toArray();  
     return messageSource.getMessage("my.email.subject", params, locale);  
    } 
+0

È vostra intenzione di fare in modo che si sta cablato correttamente con questo test? O stai pianificando di scriverne uno per ogni lingua che supporti? Anche il test sopra riportato è un test unitario o un test di integrazione? –

+0

l'idea era meno di controllare il cablaggio della molla, ma più per verificare le varie lingue man mano che vengono supportate, e per verificare la correttezza della chiave in .properties e il testo. Ho semplificato i parametri ai fini della leggibilità, ma ho verificato la loro correttezza desiderata. – Peter

risposta

27

C'è già un MessageSource in unit test in Grails, è uno StaticMessageSource (vedi http://static.springsource.org/spring/docs/2.5.4/api/org/springframework/context/support/StaticMessageSource.html), è possibile aggiungere i messaggi finti con il metodo addMessage:

messageSource.addMessage("foo.bar", request.locale, "My Message") 
+0

Grazie, buono a sapersi - è possibile convalidare con parametri usando una StaticMessageSource e un Messaggio con segnaposti in stile {0}? – Peter

+0

Per rispondere al mio commento, testato con i segnaposto e funziona alla grande. Grazie. – Peter

+3

So che questa domanda è vecchia ma ho trovato utile portarmi sulla strada giusta. Ecco la mia soluzione per mettere a punto la fonte del messaggio per i test. Innanzitutto, ho ricevuto il messaggio Origine: 'MessageSource messageSource = getMessageSource()' È vero che messageSource è nei test unitari ma è vuoto. Così ho fatto come @Graem Rocher consiglia e popolato messageSource con i messaggi rilevanti per questo test. 'messageSource.addMessage (" messageService.sms.aNumber.recovery.message ", Locale.default," {0}, il tuo numero A è {1} ")' – CheddarMonkey

2

In un test di unità si può garantire che si sta cablato correttamente facendo qualcosa di simile a questo:

void testSubjectsDefaultLocale() { 
    def messageSource = new Object() 
    messageSource.metaClass.getMessage = {subject, params, locale -> 
     assert "my.email.subject" == subject 
     assert ["Passed1", "Passed2"] == params 
     assert Locale.ENGLISH == locale 
     "It Worked!!!" 
    } 
    service.messageSource = messageSource 
    String actual = service.getEmailSubjectForStandardMustGiveGiftFromBusiness(Locale.ENGLISH, Passed1 Passed2) 
    assert "It Worked!!!" == actual 
} 

Questo ti aiuterà a essere collegato correttamente, ma non garantirà che ciò che stai facendo funzioni effettivamente. Se ti senti a tuo agio, questo potrebbe funzionare per te. Se stai provando a testarlo quando dai "XYZ" al file .properties restituisce "Hello", allora questo non funzionerà per te.

+0

Grazie per l'idea. Sono meno preoccupato per il cablaggio della molla, ma vorrei caricare il mio vero grails .properties file (direttamente o tramite Spring) piuttosto che dichiararlo nel test, in quanto testare il contenuto e la correttezza della chiave è qualcosa che voglio. – Peter

4

In unit test e il lato locale del funzionale prova, a volte vuoi le proprietà reali che si trovano nella directory 18n.

Questo funziona per me:

MessageSource getI18n() { 
    // assuming the test cwd is the project dir (where application.properties is) 
    URL url = new File('grails-app/i18n').toURI().toURL() 
    def messageSource = new ResourceBundleMessageSource() 
    messageSource.bundleClassLoader = new URLClassLoader(url) 
    messageSource.basename = 'messages' 
    messageSource 
    } 

    i18n.getMessage(key, params, locale) 
Problemi correlati