简体   繁体   中英

Using Python's UnitTest Mock for a new Object

I'm trying to learn how to use Mocks for Python. 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 .

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.

Considering newone is created later when we actually call method()-method how do I use mock to test it?

You can test this by simply instantiate ProductionClass in setUp method and patch ProductionClass in test_one as follows

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

PS: I've been using mock package for this example so you probably need to install it using pip.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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