издевательство над расширенными классами в python

Я пытаюсь издеваться над библиотекой в ​​​​Python 2.7 и сталкиваюсь с проблемами. То, что я сейчас работал, но я хотел бы расширить его, чтобы иметь возможность различать разные вызовы подпроцессов. Я хотел бы сделать это, прочитав второй элемент в моем массиве аргументов, переданный в MockedPopen. Мои проблемы в том, что у меня нет доступа к этому значению, когда я создаю класс stdout внутри MockedPopen. Мой метод до этого момента заключался в том, чтобы смоделировать все до whmapicall.stdout.read(), но я не могу передать себя в этот новый класс, потому что значение еще не создано.

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")

person IdecEddy    schedule 26.09.2019    source источник


Ответы (1)


Нет необходимости, чтобы stdout был классом. Вместо этого вы можете сделать stdout свойством и заставить его возвращать объект Mock с атрибутом read, определенным как объект Mock, который при вызове возвращает нужную строку на основе аргументов, переданных в MockedPopen:

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])))
person blhsing    schedule 26.09.2019
comment
Мои проблемы заключаются в том, что я хочу изменить возвращаемое значение на основе того, что передается в мои mock_popen if self.args[1] == 'showbw': и if self.args[1] == 'getpkginfo' или первый список, который передается в subprocess.Popen. В идеале я хочу вернуть другую структуру данных в зависимости от того, какой вызов API сделан. - person IdecEddy; 26.09.2019