Python mock a base class's attribute

2019-05-31 03:55发布

For testing, I'd like to change a single Class instance's attribute (self.attr) in a base class.

# app.py
class Base():
    def __init__(self):
        self.attr = 'original_value'

    def show(self):
        print(self.attr) 

class App():
    def __init__(self):  
        self.base = Base()

Here is my attempt at mocking the Base class instance's attribute attr

# test_app.py
from mock import Mock
from app import App

def test_mock_inherited_class_instance():
    """ With mocking. Change app.base.attr from 'original_value' to 'new_value'.
    """
    app = App()
    app.base = Mock()
    app.base.attr = 'new_value'
    app.base.show() # I'd like this to show 'new_value', NOT 'original_value'

1条回答
姐就是有狂的资本
2楼-- · 2019-05-31 04:28

The instance member or instance variable of a class is different from class attribute or class property. this mocked the attr only by keeping all class attributes.

import mock
from app import App
from app import Base
import unittest
from StringIO import StringIO
class TestApp(unittest.TestCase):

    @mock.patch('sys.stdout', new_callable=StringIO)
    def test_mock_instance_var(self, mocked_stdout):

        base = Base()
        app = App()

        mock_base = mock.MagicMock(name='Base', spec=Base)
        instance = mock_base.return_value
        instance.attr.return_value = 'mmm'
        base.attr = instance.attr.return_value
        self.assertEqual(base.attr, 'mmm')

        app.base = base

        self.assertEqual(app.base.attr, 'mmm')
        # the print stdout of show()
        app.base.show()
        self.assertEqual(mocked_stdout.getvalue(), 'mmm\n')
查看更多
登录 后发表回答