2012-03-12 11 views
5

Utilizzando Django 1.3, Python 2.6predefinito tramite le impostazioni non rispettata durante i test

Avere un problema particolarmente strano per rintracciare correlate a internazionalizzazione e RequestFactory contro TestClient per testare vista.

se corro:

./manage.py test 

tutte le prove vengono (compresi quelli problematici) e superare con successo. Se corro:

./manage.py test <appname> 

test del app fallirà, lanciando un modello di rendering un'eccezione per modelli che utilizzano il codice della lingua, perché il Django lingua pensa la richiesta sta chiedendo non è un linguaggio abbiamo elencato in settings.LANGUAGES. (In questo caso è sempre stato 'it-it', il linguaggio armadio corrispondente sosteniamo di essere 'it')

Ecco un esempio di un test che non riuscirà:

class TemplateServingTestCase(TestCase): 
    def setUp(self): 
     self.app_dir  = os.path.abspath(os.path.dirname(__file__)) 
     self.gallery_root = os.path.join(self.app_dir, 'test_gallery') 
     self.gallery_url = '/' 
     self.request  = RequestFactory().get('/') 

    def test_404_invalid_category(self): 
     self.assertRaises(Http404, gallery_page, 
      self.request, 
      'bad-category', 
      self.gallery_root, 
      self.gallery_url 
     ) 

Questo problema non sarà si verificano se il TestClient di django viene utilizzato per fare una richiesta a un URL che chiama una vista particolare. Tuttavia, se la stessa vista viene semplicemente chiamata con il risultato di RequestFactory ottieni o metti i metodi , genererà l'errore sopra riportato.

Sembra che quando si utilizza il metodo RequestFactory, il file di impostazioni non venga rispettato. Mi manca qualcosa di semplice qui?

Informazioni aggiuntive

impostazioni internazionali applicabili

LANGUAGE_CODE = 'en' 
LANGUAGES = (
    ('en', 'English'), 
    ('de', 'Deutsch'), 
    ('es', 'Espanol'), 
    ('fr', 'Francaise'), 
    ('it', 'Italiano'), 
    ('pt-br', 'Portugues (Brasil)'), 
) 

middleware attivo

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.middleware.locale.LocaleMiddleware', 
    'services.middleware.LegacyIntegrationMiddleware', 
) 

risposta

5

Ci sono 2 possibilità:

a) avete 'django.middleware.locale.LocaleMiddleware' in settings.MIDDLEWARE_CLASSES.

In questo caso, il client utilizza settings.LANGUAGE_CODE.

b) Non è così.

In tal caso, si dovrebbe impostare la lingua del genere da qualche parte nel vostro modulo tests.py:

from django.utils.translation import activate 
... 
activate('fr-fr') 

https://code.djangoproject.com/ticket/15143

+2

Vedere le modifiche sopra, a) non funziona come previsto in questo caso. b) Risolve il problema, ma è comunque molto curioso del perché RequestFactory non rispetti il ​​file delle impostazioni. – kaptainlange

+0

Testato a) e funziona per me con le stesse versioni di Python e Django. Attenzione alle ordinazioni dei middlewares. – Stan

+0

L'impostazione 'LANGUAGE_CODE' non è valida. https://docs.djangoproject.com/en/1.3/ref/settings/#language-code – Stan

0

Tuttavia, se lo stesso punto di vista è semplicemente chiamato con il risultato di RequestFactory di ottieni o metti i metodi, genererà l'errore sopra.

immagino che si sta facendo qualcosa di simile:

from django.utils import translation 
from app.views import some_view 

# Using translation.activate is pretty well known, so I suppose you 
# also do this: 
translation.activate(<whatever language you want>) 

request_factory = RequestFactory() 
request = request_factory.get("/foo") 

response = some_view(request) 

Poi gli URL prodotti dalla richiesta hanno None invece che la lingua che si voleva. Puoi provare a utilizzare un URL con un prefisso di lingua. Puoi provare a impostare un cookie di lingua nella tua richiesta. Puoi provare a giocherellare con la sessione. Niente funziona.

Il motivo non funziona è perché si sta bypassando l'intero macchinario middleware. Stai chiamando la vista direttamente. Django non interverrà, prenderà la richiesta e passerà attraverso i middleware.

Cosa si può do è chiamare qualsiasi middleware necessario, oppure è possibile replicare ciò che fa il middleware. Al fine di ottenere un prodotto con richiesta di RequestFactory per onorare le impostazioni della lingua, ho scelto quest'ultimo e ho fatto questo:

translation.activate("en-us") 
request.LANGUAGE_CODE = "en-us" 
response = some_view(request) 

Questo è stato sufficiente per me per ottenere il prefisso lingua aggiunto ai miei URL.

Problemi correlati