Como importo a exceção Django DoesNotExist?

122

Estou tentando criar um UnitTest para verificar se um objeto foi excluído.

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

Eu continuo recebendo o erro:

DoesNotExist: Answer matching query does not exist.
BryanWheelock
fonte
Independentemente da minha resposta abaixo, essa chamada get () está excluindo a resposta em questão? Nesse caso, isso realmente deve ser um DELETE, não um GET.
Steve Jalim

Respostas:

136

Você não precisa importá-lo - como você já escreveu corretamente, DoesNotExisté uma propriedade do próprio modelo, neste caso Answer.

Seu problema é que você está chamando o getmétodo - o que gera a exceção - antes de ser passado para assertRaises. Você precisa separar os argumentos dos chamados, conforme descrito na documentação mais unittest :

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

ou melhor:

with self.assertRaises(Answer.DoesNotExist):
    Answer.objects.get(body__exact='<p>User can reply to discussion.</p>')
Daniel Roseman
fonte
1
Boa resposta, apenas o primeiro dos trechos acima será capturado como sintaxe inválida (pelo menos no Python 2.7)., Deve ser self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- ou seja, com getos argumentos de s adicionados como argumentos individuais de kw, não dentro de a ().
Martin B.
1
Augh, é claro! Eu me sinto como Dorothy aqui. Eu estava procurando alto e baixo, apenas para descobrir que estava comigo o tempo todo!
Nick S
Python 3.6 / Django 2.2 apenas a withsolução funcionou para mim.
theruss
182

Você também pode importar ObjectDoesNotExistde django.core.exceptions, se desejar uma maneira genérica e independente de modelo para capturar a exceção:

from django.core.exceptions import ObjectDoesNotExist

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

DoesNotExisté sempre uma propriedade do modelo que não existe. Nesse caso, seria Answer.DoesNotExist.

defrex
fonte
3

Uma coisa a ser observada é que o segundo parâmetro assertRaises deve ser exigível - não apenas uma propriedade. Por exemplo, tive dificuldades com esta afirmação:

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

mas isso funcionou bem:

self.assertRaises(AP.DoesNotExist, lambda: self.fma.ap)
Xiong Chiamiov
fonte
3
self.assertFalse(Answer.objects.filter(body__exact='<p>User...discussion.</p>').exists())
Chris
fonte
Isso não responde exatamente à pergunta, conforme solicitado. Mas ainda é uma solução agradável, oferecendo uma abordagem diferente para obter o resultado desejado.
cezar
0

É assim que eu faço esse teste.

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
fonte