【问题标题】:django unittest without database connection没有数据库连接的django unittest
【发布时间】:2013-05-06 15:39:24
【问题描述】:

我正在尝试编写一个单元测试来检查是否返回正确的错误消息,以防数据库连接遇到异常。我尝试使用connection.creation.destroy_test_db(':memory:'),但它没有按我的预期工作。我想我应该删除表或以某种方式切断数据库连接。有可能吗?

【问题讨论】:

  • 也许您可以引发 DatabaseError 并捕获它。 from django.db import DatabaseError raise DatabaseError 这里是默认django异常列表docs.djangoproject.com/en/dev/ref/exceptions
  • 我很困惑。这个问题的标题是“没有连接”,但是在你说你试图断言出现异常时返回消息的正文中。像什么?重复密钥?标题和正文不太匹配,我只是感到困惑。澄清一下?
  • 没有连接到数据库会引发 DatabaseError 异常,这是我试图导致并断言我的 webapp 在这种情况下打印的错误消息

标签: python django unit-testing testing


【解决方案1】:

当使用pymysql 时,我正在寻找 django 的实际 http 响应代码,以防数据库连接超时。当pymysql 引发OperationalError 时,以下测试确认它是401 Unauthorized

from unittest.mock import patch

import pymysql
from django.test import TestCase, Client


class TestDatabaseOutage(TestCase):
    client = None

    def setUp(self):
        self.client = Client()

    def test_database_connection_timeout_returns_401(self):
        with patch.object(pymysql, 'connect') as connect_method:
            message = "Can't connect to MySQL server on 'some_database.example.com' ([Errno 110] Connection timed out)"
            connect_method.side_effect = pymysql.OperationalError(2003, message)
            response = self.client.get('/')
            self.assertEqual(response.status_code, 401)

【讨论】:

    【解决方案2】:

    我在演示文稿Testing and Django by Carl Meyer 中找到了答案。这是我的做法:

    from django.db import DatabaseError
    from django.test import TestCase
    from django.test.client import Client
    import mock
    
    class NoDBTest(TestCase):
        cursor_wrapper = mock.Mock()
        cursor_wrapper.side_effect = DatabaseError
    
        @mock.patch("django.db.backends.util.CursorWrapper", cursor_wrapper)
        def test_no_database_connection(self):
            response = self.client.post('/signup/', form_data)
            self.assertEqual(message, 'An error occured with the DB')
    

    【讨论】:

      【解决方案3】:

      听起来这是mocking 的工作。例如,如果您使用的是 MySQL,则可以在 connect 方法上放置一个 side_effect,如下所示:

      from django.test import TestCase
      from mock import patch
      import MySQLdb
      
      
      class DBTestCase(TestCase):
          def test_connection_error(self):
              with patch.object(MySQLdb, 'connect') as connect_method:
                  connect_method.side_effect = Exception("Database Connection Error")
      
                  # your assertions here
      

      希望对您有所帮助。

      【讨论】:

      • 感谢您的回复!我的做法略有不同,请参阅我的回答。
      猜你喜欢
      • 2018-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-26
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多