¿Cómo importo la excepción Django DoesNotExist?

122

Estoy tratando de crear un UnitTest para verificar que se haya eliminado un objeto.

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>'))

Sigo recibiendo el error:

DoesNotExist: Answer matching query does not exist.
BryanWheelock
fuente
Sin relación con mi respuesta a continuación, ¿es esa llamada get () eliminar la respuesta en cuestión? Si es así, eso realmente debería ser DELETE, no GET.
Steve Jalim

Respuestas:

136

No necesita importarlo, como ya ha escrito correctamente, DoesNotExistes una propiedad del modelo en sí, en este caso Answer.

Su problema es que está llamando al getmétodo, que genera la excepción, antes de pasarlo assertRaises. Debe separar los argumentos del invocable, como se describe en la documentación de la prueba de unidad :

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

o mejor:

with self.assertRaises(Answer.DoesNotExist):
    Answer.objects.get(body__exact='<p>User can reply to discussion.</p>')
Daniel Roseman
fuente
1
. Buena respuesta, sólo el primero de los fragmentos anteriores serán capturados como sintaxis no válida (por lo menos por Python 2.7), debe ser self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- es decir, con getargumentos 's añadido como args kw individuales, no dentro de una ().
Martin B.
1
Augh, por supuesto! Me siento como Dorothy aquí. ¡Estaba buscando por todas partes, solo para descubrir que estaba conmigo todo el tiempo!
Nick S
Python 3.6 / Django 2.2 solo la withsolución funcionó para mí.
theruss
183

También puede importar ObjectDoesNotExistdesde django.core.exceptions, si desea una forma genérica e independiente del modelo para detectar la excepción:

from django.core.exceptions import ObjectDoesNotExist

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

DoesNotExistsiempre es una propiedad del modelo que no existe. En este caso lo sería Answer.DoesNotExist.

defrex
fuente
3

Una cosa a tener en cuenta es que el segundo parámetro assertRaises debe ser invocable, no solo una propiedad. Por ejemplo, tuve dificultades con esta declaración:

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

pero esto funcionó bien:

self.assertRaises(AP.DoesNotExist, lambda: self.fma.ap)
Xiong Chiamiov
fuente
3
self.assertFalse(Answer.objects.filter(body__exact='<p>User...discussion.</p>').exists())
Chris
fuente
Esto no responde exactamente la pregunta solicitada. Pero sigue siendo una buena solución, ya que ofrece un enfoque diferente para obtener el resultado deseado.
cezar
0

Así es como hago esa prueba.

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
fuente