Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python—如何正确模拟类方法中的cls参数以引用静态变量_Python_Mocking_Python Unittest_Class Method_Static Variables - Fatal编程技术网

Python—如何正确模拟类方法中的cls参数以引用静态变量

Python—如何正确模拟类方法中的cls参数以引用静态变量,python,mocking,python-unittest,class-method,static-variables,Python,Mocking,Python Unittest,Class Method,Static Variables,背景 Python及其unittest模块相对较新。在测试中模拟静态类变量时遇到问题 (仅当原始类方法通过其第一个参数cls引用其自己的类变量时) 示例: 正在测试的类和类方法的简化版本: a.py class A: # class variable my_list = [] @classmethod def my_method(cls, item): print cls # [] unable to mock this, why? print A #

背景

Python及其unittest模块相对较新。在测试中模拟静态类变量时遇到问题

(仅当原始类方法通过其第一个参数cls引用其自己的类变量时)

示例:

正在测试的类和类方法的简化版本:

a.py
class A:
  # class variable
  my_list = []

  @classmethod
  def my_method(cls, item):
    print cls  # []  unable to mock this, why?
    print A    # [1,2,3] mocked as intended
    cls.my_list.append(item)
测试:

import unittest
from mock import patch
from a import A

class Test(unittest.testCase):
  def test_my_method(self):
    with patch("a.A") as mock_A:

      # mocking the class variable
      mock_A.my_list = [1,2,3]

      # test call class method
      A.my_method(4)

      # assert the appended list to expected output
      self.assertEqual(mock_A.my_list, [1,2,3,4])
      # should evaluate to true, but  fails the test

if __name__ == "__main__":
  unittest.main()
问题

  • 为什么mock只修补A引用而不修补cls引用

  • 为了成功地修补cls参数,解决方案应该朝哪个方向发展,这样类方法就可以通过上面所示的测试


  • 您已经在测试模块中导入了
    A
    ,因此您已经有了对原始未修补
    A
    的引用,这就是您在上所称的
    my_方法

  • 为什么mock只修补A引用而不修补cls引用
  • 因为这就是你所修补的。修补程序通过拦截名称查找来工作,它不会(也不能)在适当的位置替换对象。如果要修补具有多个名称的对象(
    A
    cls
    ,在本例中),则必须修补每个名称查找

  • 为了成功地修补cls参数,解决方案应该朝哪个方向发展,这样类方法就可以通过上面所示的测试
  • 最好直接修补class属性:

    class Test(unittest.TestCase):
    
      def test_my_method(self):
          with patch("a.A.my_list", [1,2,3]):
              A.my_method(4)
              self.assertEqual(A.my_list, [1,2,3,4])
          self.assertEqual(A.my_list, [])  # note: the mock is undone here
    

    这工作做得很好,谢谢你的解释。接下来的问题是,是否可以用cls代替a.a?或者这样做是不好的做法