Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在utils.py的Django单元测试中模拟失败_Python_Django_Unit Testing_Python 3.x_Mocking - Fatal编程技术网

Python 在utils.py的Django单元测试中模拟失败

Python 在utils.py的Django单元测试中模拟失败,python,django,unit-testing,python-3.x,mocking,Python,Django,Unit Testing,Python 3.x,Mocking,我正在尝试为名为search\u ldap()的函数编写单元测试,该函数在给定特定用户名的情况下搜索ldap服务器。下面是utils.py中的函数定义(注意:我使用的是Python 3): 当然,我不想在测试期间实际连接到ldap.example.com,所以我决定使用Python模拟unittests中的Server()和Connection()类。以下是测试代码: from unittest import mock from django.test import TestCase class

我正在尝试为名为
search\u ldap()
的函数编写单元测试,该函数在给定特定用户名的情况下搜索ldap服务器。下面是
utils.py
中的函数定义(注意:我使用的是Python 3):

当然,我不想在测试期间实际连接到
ldap.example.com
,所以我决定使用Python模拟unittests中的
Server()
Connection()
类。以下是测试代码:

from unittest import mock
from django.test import TestCase
class LdapTest(TestCase):
    @mock.patch('ldap3.Server')
    @mock.patch('ldap3.Connection')
    def test_search_ldap(self, mockConnection, mockServer):
        from .utils import search_ldap
        search_ldap('username')
        self.assertTrue(mockServer.called)
        self.assertTrue(mockConnection.called)
此测试只是断言已实例化模拟服务器和连接对象。但是,它们不会,因为当我使用
/manage.py test
运行测试时,我收到以下错误:

Creating test database for alias 'default'...
F.
======================================================================
FAIL: test_search_ldap (uvt_user.tests.LdapTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/mock.py", line 1142, in patched
    return func(*args, **keywargs)
  File "/home/jj/projects/autodidact/uvt_user/tests.py", line 28, in test_search_ldap
    self.assertTrue(mockServer.called)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 2 tests in 0.030s

FAILED (failures=1)
Destroying test database for alias 'default'...

为什么我的考试不及格?如何才能成功模拟
ldap3
的服务器和连接类?

要模拟类,您应该使用所需的方法提供它的伪实现。例如:

class FakeServer:
    def call():
        pass

class LdapTest(TestCase):
    @mock.patch('ldap3.Server', FakeServer)
    def test_search_ldap(self):
        <do you checks here>
class FakeServer:
def call():
通过
类LdapTest(测试用例):
@mock.patch('ldap3.Server',FakeServer)
def测试搜索ldap(自):
使用
patch()
在名称空间中查找对象时,对其进行修补非常重要。这将在文档的一节中解释。这两者之间有着根本的区别

from ldap3 import Server
server = Server()

在第一种情况下(也是原始问题中的情况),名称“Server”属于当前模块。在第二种情况下,名称“Server”属于定义它的ldap3模块。以下Django unittest修补了正确的“服务器”和“连接”名称,并应按预期工作:

from unittest import mock
from django.test import TestCase
class LdapTest(TestCase):
    @mock.patch('appname.utils.Server')
    @mock.patch('appname.utils.Connection')
    def test_search_ldap(self, mockConnection, mockServer):
        from .utils import search_ldap
        search_ldap('username')
        self.assertTrue(mockServer.called)
        self.assertTrue(mockConnection.called)
好的,根据这个例子,你也可以省略一个伪实现,用一个参数调用
patch()
。尽管如此,我还是尝试了您的解决方案,utils.py仍然导入原始的
ldap3
模块,而不是模拟的模块。
import ldap3
server = ldap3.Server()
from unittest import mock
from django.test import TestCase
class LdapTest(TestCase):
    @mock.patch('appname.utils.Server')
    @mock.patch('appname.utils.Connection')
    def test_search_ldap(self, mockConnection, mockServer):
        from .utils import search_ldap
        search_ldap('username')
        self.assertTrue(mockServer.called)
        self.assertTrue(mockConnection.called)