如何在 python 中模拟依赖

how to mock dependency in python

我是 python 单元测试框架的新手,在模拟依赖方面有很多困惑。

我正在尝试为 class、(check_something()):

的以下成员函数编写单元测试
class Validations:    
    def check_something(self):
        abc = os.environ['PLATFORM']
        xyz = Node()
        no_of_nodes = len(xyz.some_type_var)
        if abc != "X_PLATFORM" or no_of_nodes != 1:
            raise someException()

我们如何消除依赖性?

  1. 需要模拟 Node() ?
  2. 我们如何确保 abc 分配给 X_PLATFORM
  3. 如何将值1赋值给变量no_of_nodes?这又是从 Node() 对象派生的。

    class Node(object):
        def __init__(self):
            self.nodes = DEF()
            self.some_type_var = someclass().getType()
            self.localnode = os.environ['HOSTNAME']
            self.peertype = self.get_peer_type()
    
        def get_peer_type(self):
            return node
    

我试着写下面的单元测试。我无法检查失败和通过条件。我不确定它是否正确。

class TestValidation(unittest.TestCase):

    @mock.patch.object(Node, "get_peer_type")
    @mock.patch('somefile.Node', spec=True)
    def test_1(self, mock_object1, mock_object2):
        os.environ['PLATFORM'] = 'X_PLATFORM'
        obj = Validations()
        self.assertRaises(someException, obj.check_something)

验证 class 使用 Node() Class 对象,节点 class 使用其他一些 class.

  1. 如何根据条件确定是否引发异常?

是的,您可以模拟被测代码单元外部的任何内容。这里指的是 os.environ 字典和 Node() class.

补丁需要应用到您的代码所在的模块;如果 somefileValidations 是同一个模块,则 @mock.patch('somefile.Node', spec=True) 是正确的;看看 Where to patch section 为什么会这样。

我不确定使用 spec=True 在这里是否有用;您的 Node 属性是在 Node.__init__ 中创建的所有实例属性,因此它们在 class 中不可用,这正是规范所告知的内容。如果您真的想设置规格,请参阅 autospeccing 部分了解如何克服这个问题。

abc 是从 os.environ 设置的,您可以使用 patch.dict() object 来根据需要修补该词典。

xyz = len(xyz.some_type_var) 只需将 some_type_var 属性设置为具有正确长度的对象, 通过设置 xyz.some_type_var.__len__.return_value ,因为它是为 len() 函数调用的 xyz.some_type_var.__len__() 方法。

因此,要进行测试,您需要这样做:

class TestValidation(unittest.TestCase):
    @mock.patch('somefile.Node')
    def test_1(self, mock_node):
        # set up the Node() instance, with the correct length
        node_instance = mock_node.return_value
        node_instance.some_type_var.__len__ = 2
        # or, alternatively, node_instance.some_type_var = (1, 2)

        # set up os.environ['PLATFORM']
        with mock.patch.dict('os.environ', PLATFORM='X_PLATFORM'):
            obj = Validations()
            with self.assertRaises(someException):
                obj.check_something()