Bagaimana saya mengimpor pengecualian Django DoesNotExist?

122

Saya mencoba membuat UnitTest untuk memverifikasi bahwa sebuah objek telah dihapus.

from django.utils import unittest
def test_z_Kallie_can_delete_discussion_response(self):
  ...snip...
  self._driver.get("http://localhost:8000/questions/3/want-a-discussion") 
  self.assertRaises(Answer.DoesNotExist, Answer.objects.get(body__exact = '<p>User can reply to discussion.</p>'))

Saya terus mendapatkan kesalahan:

DoesNotExist: Answer matching query does not exist.
BryanWheelock
sumber
Tidak terkait dengan jawaban saya di bawah ini, apakah panggilan get () itu menghapus Jawaban yang dimaksud? Jika demikian, itu benar-benar harus menjadi HAPUS, bukan GET.
Steve Jalim

Jawaban:

136

Anda tidak perlu mengimpornya - karena Anda sudah menulis dengan benar, DoesNotExistadalah properti model itu sendiri, dalam kasus ini Answer.

Masalah Anda adalah Anda memanggil getmetode - yang memunculkan pengecualian - sebelum diteruskan ke assertRaises. Anda perlu memisahkan argumen dari callable, seperti yang dijelaskan dalam dokumentasi unittest :

self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact='<p>User can reply to discussion.</p>')

atau lebih baik:

with self.assertRaises(Answer.DoesNotExist):
    Answer.objects.get(body__exact='<p>User can reply to discussion.</p>')
Daniel Roseman
sumber
1
Jawaban yang bagus, hanya potongan pertama di atas yang akan ditangkap sebagai sintaks yang tidak valid (setidaknya oleh Python 2.7)., Harus self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- yaitu dengan getargumen ditambahkan sebagai argumen kw individu, bukan di dalam a ().
Martin B.
1
Augh, tentu saja! Saya merasa seperti Dorothy di sini. Saya sedang mencari tinggi dan rendah, hanya untuk menemukan itu dengan saya selama ini!
Nick S
Python 3.6 / Django 2.2 hanya withsolusi yang bekerja untuk saya.
theruss
183

Anda juga dapat mengimpor ObjectDoesNotExistdari django.core.exceptions, jika Anda menginginkan cara umum, model-independen untuk menangkap pengecualian:

from django.core.exceptions import ObjectDoesNotExist

try:
    SomeModel.objects.get(pk=1)
except ObjectDoesNotExist:
    print 'Does Not Exist!'
Chris Pratt
sumber
10

DoesNotExistselalu merupakan properti model yang tidak ada. Dalam hal ini akan terjadi Answer.DoesNotExist.

defrex
sumber
3

Satu hal yang harus diperhatikan adalah parameter kedua menjadi assertRaises harus dapat dipanggil - bukan hanya properti. Misalnya, saya mengalami kesulitan dengan pernyataan ini:

self.assertRaises(AP.DoesNotExist, self.fma.ap)

tapi ini bekerja dengan baik:

self.assertRaises(AP.DoesNotExist, lambda: self.fma.ap)
Xiong Chiamiov
sumber
3
self.assertFalse(Answer.objects.filter(body__exact='<p>User...discussion.</p>').exists())
Chris
sumber
Ini tidak menjawab pertanyaan seperti yang diminta. Tapi ini masih merupakan solusi yang bagus, menawarkan pendekatan berbeda untuk mendapatkan hasil yang diinginkan.
cezar
0

Beginilah cara saya melakukan tes semacam itu.

from foo.models import Answer

def test_z_Kallie_can_delete_discussion_response(self):

  ...snip...

  self._driver.get("http://localhost:8000/questions/3/want-a-discussion") 
  try:
      answer = Answer.objects.get(body__exact = '<p>User can reply to discussion.</p>'))      
      self.fail("Should not have reached here! Expected no Answer object. Found %s" % answer
  except Answer.DoesNotExist:
      pass # all is as expected
Steve Jalim
sumber