断言__init__是用正确的参数调用的 [英] Asserting that __init__ was called with right arguments

查看:76
本文介绍了断言__init__是用正确的参数调用的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用python模拟来断言特定对象是使用正确的参数创建的.这是我的代码的样子:

I'm using python mocks to assert that a particular object was created with the right arguments. This is how my code looks:

class Installer:
    def __init__(foo, bar, version):
        # Init stuff
        pass
    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):
        # cleanup
        pass

    def install(self):
        # Install stuff
        pass

class Deployer:
    def deploy(self):
        with Installer('foo', 'bar', 1) as installer:
            installer.install()

现在,我想断言installer是用正确的参数创建的.这是我到目前为止的代码:

Now, I want to assert that installer was created with the right arguments. This is the code I have so far:

class DeployerTest(unittest.TestCase):
    @patch('Installer', autospec=True)
    def testInstaller(self, mock_installer):
        deployer = Deployer()
        deployer.deploy()

        # Can't do this :-(
        mock_installer.__init__.assert_called_once_with('foo', 'bar', 1)

这是我得到的错误:

  File "test_deployment.py", line .., in testInstaller
    mock_installer.__init__.assert_called_once_with('foo', 'bar', 1)
AttributeError: 'function' object has no attribute 'assert_called_once_with'


这是固定代码(称为test.py).谢谢,所有!


Here is the fixed code (Call it test.py). Thanks, all!

import unittest
from mock import patch

class Installer:
    def __init__(self, foo, bar, version):
        # Init stuff
        pass

    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):
        # cleanup
        pass

    def install(self):
        # Install stuff
        pass

class Deployer:
    def deploy(self):
        with Installer('foo', 'bar', 1) as installer:
            installer.install()

class DeployerTest(unittest.TestCase):
    @patch('tests.test.Installer', autospec=True)
    def testInstaller(self, mock_installer):
        deployer = Deployer()
        deployer.deploy()

        # Can't do this :-(
        # mock_installer.__init__.assert_called_once_with('foo', 'bar', 1)

        # Try this instead
        mock_installer.assert_called_once_with('foo', 'bar', 1)

推荐答案

因此,您收到的错误消息实际上是因为您没有正确检查模拟.在这里,您需要了解的是,在装饰器中您最终要说的是,对Installer的调用将改为释放Mock对象.

So, the error message you are getting is actually because you are not checking your mock properly. What you have to understand here is that in your decorator you are ultimately saying that, the call to Installer will relturn a Mock object instead.

因此,对于与修补程序有关的对Installer()的任何调用,该调用的返回值将改为调用Mock().

Therefore, for any call to Installer() with respect to where you are patching, the return value of that will call Mock() instead.

因此,您实际上要检查的断言只是在mock_installer处,而不是在mock_installer.__init__.处:

So, the assertion you actually want to check is simply at the mock_installer, and not the mock_installer.__init__.:

mock_installer.assert_called_once_with('foo', 'bar', 1)

这是对您的代码所做的修改:

Here is the modification made to your code:

class DeployerTest(unittest.TestCase):

    @patch('Installer', autospec=True)
    def testInstaller(self, mock_installer):
        deployer = Deployer()
        deployer.deploy()

        mock_installer.assert_called_once_with('foo', 'bar', 1)

一些额外的信息可以提供更多的解释,如果您现在正在测试是否在上下文管理器中调用了install,则必须在此处意识到实际上必须在__enter__内部进行检查,因此结构类似于这个:

A little extra information to provide some more explanation, if you were testing now if install was called within your context manager, you have to realize here that you actually have to check inside your __enter__, so a structure would be like this:

为清楚起见,在您的测试方法中创建一个模拟对象,然后:

For clarity sake create a mock_obj in your test method and:

mock_obj = mock_installer.return_value

现在,在您的上下文管理器中,您将需要查看对__enter__()的调用.如果您不知道为什么这样做,请阅读上下文管理器.

Now, within your context manager, you will need to look inside the call to __enter__(). In case you don't know why this is, read up on context managers.

因此,请记住,您只需执行以下检查:

So, with that in mind, you simply perform your check as:

mock_obj.__enter__().install.assert_called_once_with()

这篇关于断言__init__是用正确的参数调用的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆