2013-04-22 33 views
19

Django uygulamalarımdan biri için sınamalar yazıyordum ve şu anda bu soruna geçici bir çözüm bulmak istiyordum. Farklı durumlar için django.contrib.messages kullanarak mesaj gönderen bir görünüm var. Görünüm, aşağıdaki gibi bir şeye benziyor. ŞimdiDjango Sınama - iletileri yeniden yönlendiren bir görünüm için iletileri denetle

from django.contrib import messages 
from django.shortcuts import redirect 

import custom_messages 

def some_view(request): 
    """ This is a sample view for testing purposes. 
    """ 

    some_condition = models.SomeModel.objects.get_or_none(
     condition=some_condition) 
    if some_condition: 
     messages.success(request, custom_message.SUCCESS) 
    else: 
     messages.error(request, custom_message.ERROR) 
    redirect(some_other_view) 

, bu görünüm bir yönlendirme kullandığından messages içeren context sözlüğünü içermez Bu görünüm client.get 'ın tepkisini test ederken. Şablonlar oluşturan görünümler için messages = response.context.get('messages')'u kullanarak ileti listesine erişebiliriz. Yeniden yönlendiren bir görünüm için messages erişimini nasıl alabiliriz?

+0

emin değil ise: 'yönlendirme (ters (some_other_view) + '? user_added = true') ' –

+0

Aslında testimde kullandığım koşulu test ediyorum. Burada gönderilen mesajın açık bir şekilde test edilmesinden bahsediyorum. – Amyth

cevap

31

client.get() numaralı aramada follow=True seçeneğini kullanın ve istemci yönlendirmeyi takip edecektir. Ardından, iletinin yönlendirdiğiniz görünümün bağlamında olduğunu test edebilirsiniz.

def test_some_view(self): 
    # use follow=True to follow redirect 
    response = self.client.get('/some-url/', follow=True) 

    # don't really need to check status code because assertRedirects will check it 
    self.assertEqual(response.status_code, 200) 
    self.assertRedirects(response, '/some-other-url/') 

    # get message from context and check that expected text is there 
    message = list(response.context.get('messages'))[0] 
    self.assertEqual(message.tags, "success") 
    self.assertTrue("success text" in message.message) 
+0

Teşekkürler, işe yaradı. Yine de, 'follow = True' ifadesi kullanılarak yönlendirilen görünümü takip eden 302'den 200'e kadar beklenen yönlendirme kodu değiştirilir. – Amyth

+0

Evet, yönlendirmenin ardından yanıtın durum kodu 200 olduğu anlamına gelir. ['AssertRedirects'] var (https://docs.djangoproject.com/en/1.5/topics/testing/overview/#django.test.TestCase .Yönlendirmeyi test etmek için kullanabileceğiniz assertRedirects) yöntemi. – Alasdair

+0

yup, şu anda kullanıyorum :) – Amyth

1

görüşleriniz yönlendiriyorsunuz ve yukarıdaki çalışmıyor testi müşteriye Talebinizdeki follow=true kullanın. Yanıtla birlikte gönderilen ilk (ve sadece benim durumumda) mesajı almak için yardımcı bir işlev yazmayı bitirdim.

@classmethod 
def getmessage(cls, response): 
    """Helper method to return message from response """ 
    for c in response.context: 
     message = [m for m in c.get('messages')][0] 
     if message: 
      return message 

Sen test sınıfı içindeki bu kapsar ve bu gibi kullanmak: response geri get veya post bir bir Client almak ne

message = self.getmessage(response) 

.

Bu biraz kırılgan ama umarım bir başkasına zaman kazandırır.

+2

Bu liste kavramasına ihtiyacınız yok, sadece liste (mesajlar) veya tuple (mesajlar) kullanın. – bbrik

1

Bir 3. parti uygulaması kullanırken aynı sorunu yaşadım. Başka bir görünümde içinden (eğer bağlamı erişemez hangi) bir HttpResponseRedict döndüren bir görünümden mesajları almak istiyorsanız

, sen bu mesaj depolama temizler get_messages(request)

from django.contrib.messages import get_messages 

storage = get_messages(request) 
for message in storage: 
    do_something_with_the_message(message) 

kullanabilirsiniz daha sonra bir şablondan mesajları erişmek istiyorsanız olsa da, yani, ekleyin:

storage.used = False 
4
sen (Django 1.10 test) böyle response.wsgi_request ile get_messages() kullanabilir

:

from django.contrib.messages import get_messages 
... 
def test_view(self): 
    response = self.client.get('/some-url/') # you don't need follow=True 
    self.assertRedirects(response, '/some-other-url/') 
    # each element is an instance of django.contrib.messages.storage.base.Message 
    all_messages = [msg for msg in get_messages(response.wsgi_request)] 

    # here's how you test the first message 
    self.assertEqual(all_messages[0].tags, "success") 
    self.assertEqual(all_messages[0].message, "you have done well") 
+0

Bu benim için çalıştı, ancak Alasdair'in yöntemi herhangi bir mesaj göstermedi. Django 1.11'deyim. –

0

Alternatif yöntem alay mesajları (yönlendirme takip etmek gerekmez): Bu ihtiyacı uyacak ama ne oldu tanımlamak için değişkenler almak geçebilir

from mock import ANY, patch 
from django.contrib import messages 

@patch('myapp.views.messages.add_message') 
def test_some_view(self, mock_add_message): 
    r = self.client.get('/some-url/') 
    mock_add_message.assert_called_once_with(ANY, messages.ERROR, 'Expected message.') # or assert_called_with, assert_has_calls...