【问题标题】:mocking extended classes in python在python中模拟扩展类
【发布时间】:2019-09-26 18:15:39
【问题描述】:

我正在尝试在 Python 2.7 中模拟一个库,但遇到了问题。我目前所做的工作,但我想扩展它以区分不同的子流程调用。我想通过读取我的 args 数组中的第二个元素来做到这一点,传递给MockedPopen。我的问题是,当我在 MockedPopen 中创建类 stdout 时,我无法访问此值。到目前为止,我的方法是模拟直到 whmapicall.stdout.read() 的所有内容,但我似乎无法将 self 传递给这个新类,因为尚未创建值。

class MockedPopen:
    PIPE = None
    def __init__(self, args, **kwargs):
        self.args = args
        self.returncode = 0

    def __enter__(self):
        return self

    def __exit__(self, exc_type, value, traceback):
        pass

    @classmethod
    def Popen(self, cmd , **kwargs):
        return self

    class stdout():
        stdout = '''---
data:
  acct:
    -
      bwusage:
        -
          deleted: 0
          domain: hd.tld
          usage: 771853
      deleted: 0
      limit: '88048926720'
      maindomain: hd.tld
      owner: root
      reseller: 0
      totalbytes: 771853
      user: hd
  month: 9
  reseller: root
  totalused: 232307616
  year: 2019
metadata:
  command: showbw
  reason: OK
  result: 1
  version: 1'''

        @classmethod
        def read(self):
            return self.stdout

我的测试课

 class TestInit:
     @mock.patch('cpquotafix.subprocess', MockedPopen)
     def testUsername(self):
         user = cpquotafix.User("eddy","cthulhu","hd.tld","root",  None ,"10000")
         assert user.username == "eddy"

我要修补的代码

def setBandwidthLimit(self):
    whmapicall   = subprocess.Popen(["whmapi1" , "showbw", 'searchtype=user', 'search=^%s$' % self.username], stdout=subprocess.PIPE)
    whmapireturn = whmapicall.stdout.read().split("\n")
def setPackageQuota(self):
    whmapicall   = subprocess.Popen(["whmapi1" , "getpkginfo", "pkg=%s" % self.plan], stdout=subprocess.PIPE)
    whmapireturn = whmapicall.stdout.read().split("\n")

【问题讨论】:

    标签: python python-2.7 python-mock


    【解决方案1】:

    stdout 没有必要成为一个类。您可以改为将stdout 设为属性,并使其返回一个read 属性定义为Mock 对象的Mock 对象,该对象在调用时根据传递给@987654326 的参数返回所需的字符串@:

    class MockedPopen:
        def __init__(self, *args, **kwargs):
            self.args = args
    
        @property
        def stdout(self):
            return mock.Mock(read=mock.Mock(return_value='''blah blah
    metadata:
      command: {}
    blah blah'''.format(self.args[1])))
    

    【讨论】:

    • 我的问题是我想根据传递给我的 mock_popen if self.args[1] == 'showbw':if self.args[1] == 'getpkginfo' 或传递给 subprocess.Popen 的第一个列表来更改返回值。理想我想根据所进行的 API 调用类型返回不同的数据结构。
    猜你喜欢
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-14
    • 2018-01-04
    • 2021-03-15
    • 2010-09-07
    相关资源
    最近更新 更多