当前位置: 首页 > 面试题库 >

如何在带有unittest setUp的python中正确使用模拟

朱运诚
2023-03-14
问题内容

在尝试学习TDD的过程中,尝试学习单元测试并在python中使用模拟。慢慢掌握它,但不确定我是否正确执行此操作。预先警告:由于供应商API是预编译的2.4
pyc文件,因此我正在使用python 2.4进行卡住,因此我正在使用模拟0.8.0和unittest(不是unittest2)

在“ mymodule.py”中给出此示例代码

import ldap

class MyCustomException(Exception):
    pass

class MyClass:
    def __init__(self, server, user, passwd):
        self.ldap = ldap.initialize(server)
        self.user = user
        self.passwd = passwd

    def connect(self):
        try:
            self.ldap.simple_bind_s(self.user, self.passwd)
        except ldap.INVALID_CREDENTIALS:
            # do some stuff
            raise MyCustomException

现在在我的测试用例文件“
test_myclass.py”中,我要模拟ldap对象。ldap.initialize返回ldap.ldapobject.SimpleLDAPObject,因此我认为这是我必须模拟的方法。

import unittest
from ldap import INVALID_CREDENTIALS
from mock import patch, MagicMock
from mymodule import MyClass

class LDAPConnTests(unittest.TestCase):
    @patch('ldap.initialize')
    def setUp(self, mock_obj):
        self.ldapserver = MyClass('myserver','myuser','mypass')
        self.mocked_inst = mock_obj.return_value

    def testRaisesMyCustomException(self):
        self.mocked_inst.simple_bind_s = MagicMock()
        # set our side effect to the ldap exception to raise
        self.mocked_inst.simple_bind_s.side_effect = INVALID_CREDENTIALS
        self.assertRaises(mymodule.MyCustomException, self.ldapserver.connect)

    def testMyNextTestCase(self):
        # blah blah

带我几个问题:

  1. 看起来正确吗?:)
  2. 这是尝试模拟在我正在测试的类中实例化的对象的正确方法吗?
  3. 可以在setUp上调用@patch装饰器,还是会引起怪异的副作用?
  4. 无论如何,有没有要引发ldap.INVALID_CREDENTIALS异常的模拟而不必将异常导入到我的测试用例文件中?
  5. 我应该改用patch.object(),如果是,怎么办?

谢谢。


问题答案:

您可以patch()用作类装饰器,而不仅可以用作函数装饰器。然后,您可以像以前一样传递模拟函数:

@patch('mymodule.SomeClass')
class MyTest(TestCase):

    def test_one(self, MockSomeClass):
        self.assertIs(mymodule.SomeClass, MockSomeClass)

请参阅:将相同的补丁程序应用于每种测试方法(还列出了替代方法)

如果要对所有测试方法进行修补,则在setUp上以这种方式设置修补程序更有意义。



 类似资料:
  • 我刚刚开始使用覆盖率。于是决定做一个简单的测试来检查它是如何工作的。 Sample.py 测验派克 如您所见,我所有的代码都覆盖了测试,py.test说它们都通过了。我希望Coverage.py显示100%的覆盖率。嗯,不。 然后我添加了这段代码: 并删除了所有测试功能。在那之后,是保险范围。py显示100%: 为什么会这样?我们不应该买保险。py显示代码测试覆盖率,而不仅仅是执行覆盖率?我读过官

  • 我一直在研究HandlerThread类,因为最初我使用的是一个简单的线程和处理程序,但是在Android中使用NetworkOnMainThreadException出现了一个裁剪器。 我似乎无法理解如何将套接字之类的东西引入到HandlerThread中,您可以在其中运行阻塞代码。但是您不能使用HandlerThread来实现这一点,因为您不应该覆盖run,因为这是循环器所在的位置。 而且我不

  • 问题内容: 我在python 2.7中有一些代码,我想将它们全部转换成python 3.3代码。我知道可以使用2to3,但是我不确定如何使用它。 问题答案: 安装以下模块,该模块将2to3命令直接添加到entry_points。 正如在2to3 docs 上所写,要将整个项目从一个目录树转换到另一个目录树,请使用:

  • 问题内容: 在Python中使用相对导入有一个缺点,您将无法再独立运行模块,因为您将得到一个异常: 为了能够执行以下所有操作,我应该如何修改示例代码:和 我正在寻找适用于python 2.6+(包括3.x)的解决方案。 问题答案: 首先,我假设您意识到您编写的内容将导致循环导入问题,因为foo导入bar反之亦然;尝试添加 to test.py,您将看到它失败。必须更改示例才能正常工作。 因此,您要

  • 问题内容: 从官方教程中: 在卸载和销毁组件之前立即调用。使用此方法执行任何必要的清除,例如使计时器无效,取消网络请求或清除在其中创建的所有DOM元素。 我了解“使计时器无效”。可以用终止。但是我不理解“清理在中创建的任何DOM元素”,我可以看到这种情况的示例吗? 问题答案: 如果网络请求发送库支持中止正在进行的网络请求调用,则绝对可以在方法中调用该请求。 但是,与清理元素有关。根据目前的经验,我

  • 问题内容: 我一直在尝试在Node.js中调用D3。我首先尝试使用脚本标签从D3的网站导入d3.v2.js D3的作者建议一个人应该“ npm install d3” …我做到了,我可以在节点控制台中成功调用它: 但是,当尝试使用“ node app.js”从app.js调用它时,我得到: 我意识到,D3的作者在其他地方已经明确规定了应该使用画布: https://github.com/mbost