Django / Python unittesting: Wie Force Exception of Try / Except Block zu erzwingen

Gibt es irgendeine Möglichkeit, den Auslösungsblock zu erzwingen, damit ich die Fehlermeldungen / Handhabung mit Unit-Tests überprüfen kann? Beispielsweise:

Views.py

def get_books(request): ... try: book = Books.objects.get_or_create(user=request.user) except: messages.error(request, 'Unable to create new book!') return HttpResponseRedirect(reverse('my_books')) # more try/except cases 

Also in diesem Beispiel könnte ich versuchen, einen ORM-Fehler zu simulieren, oder ich kann versuchen, einen ungültigen Benutzer für diesen Fall zu senden. Aber gibt es einen allgemeinen Weg, um Ausnahmen zu werfen (ich bin offen für die Verwendung von Bibliotheken) ? Mock zum Beispiel. Oder gibt es noch eine andere Methode, um unittest zu benutzen, um Ausnahmen zu erzwingen? Offensichtlich gibt es viele Versuche / außer Blöcke während des Codes, also suche ich irgendeine Hilfe.

One Solution collect form web for “Django / Python unittesting: Wie Force Exception of Try / Except Block zu erzwingen”

Sie können unittest.mock , um es zu tun. Du sollst das Books.objects Objekt von patch.object und side_effect , um Exception zu heben. Ein vollständiger Test für Ihre Methode Ausnahme Verhalten sollte:

 import unittest from unittest.mock import patch, ANY from django.test.client import RequestFactory class TestDjango(unittest.TestCase): @patch("your_module.messages") @patch("your_module.HttpResponseRedirect") def test_get_books_exception(self,mock_redirect,mock_messages) r = RequestFactory().get('/I_dont_konw_how_to_build_your_request/') objs = Books.objects with patch.object(objs,"get_or_create", side_effect=Exception()): self.assertIs(get_books(r),mock_redirect.return_value) mock_messages.error.assert_called_with(r, ANY) mock_redirect.assert_called_with(reverse('my_books')) 

Ich habe ANY die ANY entfernt. Ich bin mir nicht sicher, was du in deinem Code testen willst (komplettes Verhalten oder einfach weiterleiten …), trotzdem habe ich ein komplettes Beispiel geschrieben.


Wenn Ihr Projekt keine Legacy-Arbeit ist, sollten Sie Ihre Methode (und die neuen Django-ORM-Anrufe) im TDD-Stil umschreiben, wo Sie zB eine _get_books_proxy() Funktion haben, die nur die Django ORM-Methoden aufruft:

 def _get_books_proxy(request): return Books.objects.get_or_create(user=request.user) 

Und jetzt Patch _get_books_proxy() direkt von patch Dekorateur als:

 @patch("your_module.messages") @patch("your_module.HttpResponseRedirect") @patch("your_module._get_books_proxy", side_effect=Exception()) def test_get_books_exception(self,mock_get_book, mock_redirect, mock_messages) r = RequestFactory().get('/I_dont_konw_how_to_build_your_request/') self.assertIs(get_books(r),mock_redirect.return_value) mock_messages.error.assert_called_with(r, ANY) mock_redirect.assert_called_with(reverse('my_books')) 

Darüber _get_books_proxy() kann das Verhalten von _get_books_proxy() durch Patching von Books und übergeben eines einfachen Mock() :

 @patch("your_module.Books") def test__get_books_proxy(self,mock_books): r = Mock() self.assertIs(mock_books.objects.get_or_create.return_value, your_module._get_books_proxy(r)) mock_books.objects.get_or_create.assert_called_with(user=r.user) 

Jetzt hast du einen Sentinel, der dir nachgeben kann, wenn dein kritisches Punktverhalten geändert wird.

Ich entschuldige mich, wenn du Fehler findest (ich kann es nicht testen) … aber ich hoffe die Idee ist klar.

  • Mit selbst in python @ patch dekorateur
  • Kann das Python-Coverage-Modul die Zeilen in einem Unit-Test bedingt ignorieren?
  • Nase nicht laufen Django Dokthen
  • Erhalten der End-Speicher-Adresse eines Speicherbereichs über Python / Ctypes
  • Einstellung pycharm laufen django unittest
  • Unbekannter Tkinter File Dialog
  • Tkinter's event_generate Befehl ignoriert
  • Django Benutzer Setup für Nase Tests
  • Warum könnte dieser Code eventuell einen Testfall ausfallen?
  • Wie behaupte ich, dass ein Funktionsaufruf keinen Fehler mit unittest zurückgibt?
  • Python spöttische Drittanbieter-Module
  • Python ist die beste Programmiersprache der Welt.