简体   繁体   English

使用Python的UnitTest模拟对象创建新对象

[英]Using Python's UnitTest Mock for a new Object

I'm trying to learn how to use Mocks for Python. 我正在尝试学习如何为Python使用Mocks。 However I've been struggling with some basic application of it. 但是,我一直在为它的一些基本应用而苦苦挣扎。

Let's say our piece of code that I want to test is this: 假设我要测试的代码是这样的:

class ProductionClass:
    def method(self):
        newone=ProductionClass()
        newone.something(1, 2, 3)
    def something(self, a, b, c):
        pass
    def __init__(self):
        print("Test")

Which have a method which is simply create a new object of itself and calls a method of that class. 它们具有一个方法,该方法只是创建自己的新对象并调用该类的方法。

import unittest
import unittest.mock
from ProductionClass import *
from unittest.mock import *

class TestProduction(unittest.TestCase):
    def test_one(self):

        real = ProductionClass()
        real.something = MagicMock()
        real.method()
        real.something.assert_called_once_with(1, 2, 3)

if __name__ == '__main__':
    unittest.main()

Once again, this is a very simple UnitTest, basically copypasted from 26.5.1.1 of https://docs.python.org/3/library/unittest.mock-examples.html . 再一次,这是一个非常简单的UnitTest,基本上是从https://docs.python.org/3/library/unittest.mock-examples.html的 26.5.1.1复制而来。

However, this would test if real.something has been called, meanwhile the one i really want to test is if newone.something has been called. 但是,这将测试是否调用了real.something,而我真正要测试的是是否调用了newone.something。

Considering newone is created later when we actually call method()-method how do I use mock to test it? 考虑到稍后我们实际调用method()方法时会创建newone,我该如何使用模拟来测试它?

You can test this by simply instantiate ProductionClass in setUp method and patch ProductionClass in test_one as follows 您可以通过在setUp方法中实例化ProductionClass并在test_one中修补ProductionClass来进行测试,如下所示

import unittest
import ProductionClass
import mock

class TestProduction(unittest.TestCase):
    def setUp(self):
        self.real = ProductionClass.ProductionClass()

    @mock.patch("ProductionClass.ProductionClass")
    def test_one(self, mock1):
        print "From Test : %s " % mock1()
        real = self.real
        real.method()
        mock1().something.assert_called_once_with(1, 2, 3)

if __name__ == '__main__':
    unittest.main()

I just modified the production class to show that both object refers to the same instance of the mock 我刚刚修改了生产类,以表明两个对象都引用了模拟的相同实例

class ProductionClass:
    def method(self):
        newone=ProductionClass()
        print "From Production class : %s" % newone
        newone.something(1, 2, 3)
    def something(self, a, b, c):
        pass
    def __init__(self):
        print("Test")

Output: 输出:

Testing started at 5:52 PM ...
Test
From Test : <MagicMock name='ProductionClass()' id='4330372048'> 
From Production class : <MagicMock name='ProductionClass()' id='4330372048'>

Process finished with exit code 0

You can verify that both object refers the same instance of the mock object by looking the id 您可以通过查看id来验证两个对象都引用了模拟对象的相同实例

PS: I've been using mock package for this example so you probably need to install it using pip. PS:在此示例中,我一直在使用模拟软件包,因此您可能需要使用pip进行安装。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM