Макет openshift-restclient-ресурс python

#python #unit-testing #mocking #openshift

#python #модульное тестирование #издевательство #openshift

Вопрос:

Я пытаюсь написать некоторый unittest для функций, использующих клиент openshift python, поэтому мне нужно смоделировать некоторые вызовы клиента openshift.

https://github.com/openshift/openshift-restclient-python

 from kubernetes import client, config
from openshift.dynamic import DynamicClient, exceptions as openshift_exceptions


_openshift_cert_manager_api_version = 'cert-manager.io/v1'


class OCPException(Exception):
    pass


def certificate_exists(dyn_client: DynamicClient, namespace: str, certificate_name: str) -> bool:
    """ Checks if certificate already exists in namespace. """
    v1_certificates = dyn_client.resources.get(api_version=_openshift_cert_manager_api_version, kind='Certificate')
    try:
        v1_certificates.get(namespace=namespace, name=certificate_name)
    except openshift_exceptions.NotFoundError:
        return False
    except openshift_exceptions as Error:
        raise OCPException(Error)
    return True
 
 import unittest
from unittest import mock
from openshift.dynamic import DynamicClient
from awscertmanager import ocp


class TestCertificateExists(unittest.TestCase):
    def test_certificate_exists(self):
        mock_client = mock.create_autospec(DynamicClient)
        ocp.certificate_exists(mock_client, namespace='dummy', certificate_name='tls-wildcard-dummy')
        mock_client.resources.get.assert_called_with(
            api_version=ocp._openshift_cert_manager_api_version,
            kind='Certificate'
        )


if __name__ == '__main__':
    unittest.main()
 

Этот тест отлично работает с первым вызовом, но я пытался узнать, вызывается ли второй вызов (v1_certificates.get) без успеха.

Я пробовал издеваться над классом ресурсов, но получаю эту ошибку.

 import unittest
from unittest import mock
from openshift.dynamic import DynamicClient, Resource
from awscertmanager import ocp


class TestCertificateExists(unittest.TestCase):
    @mock.patch.object(Resource, 'get')
    def test_certificate_exists(self, mock_get):
        mock_client = mock.create_autospec(DynamicClient)
        ocp.certificate_exists(mock_client, namespace='dummy', certificate_name='tls-wildcard-dummy')
        mock_client.resources.get.assert_called_with(
            api_version=ocp._openshift_cert_manager_api_version,
            kind='Certificate'
        )
        mock_get.assert_called_with(namespace='dummy', name='tls-wildcard-dummy')


if __name__ == '__main__':
    unittest.main()
 
 Error
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/case.py", line 60, in testPartExecutor
    yield
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/case.py", line 676, in run
    self._callTestMethod(testMethod)
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/case.py", line 633, in _callTestMethod
    method()
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/mock.py", line 1322, in patched
    with self.decoration_helper(patched,
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py", line 113, in __enter__
    return next(self.gen)
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/mock.py", line 1304, in decoration_helper
    arg = exit_stack.enter_context(patching)
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py", line 425, in enter_context
    result = _cm_type.__enter__(cm)
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/mock.py", line 1393, in __enter__
    original, local = self.get_original()
  File "/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/mock.py", line 1366, in get_original
    raise AttributeError(
AttributeError: <class 'openshift.dynamic.resource.Resource'> does not have the attribute 'get'
 

Ответ №1:

Наконец, он работает над классом DynamicClient и некоторыми вызовами:

    @mock.patch('awscertmanager.ocp.DynamicClient')
    def test_certificate_exists_true(self, mock_dynamicclient):
        mock_resource = mock.Mock()
        mock_resource.get.return_value = None
        mock_dynamicclient.resources.get.return_value = mock_resource
        result = ocp.certificate_exists(mock_dynamicclient, namespace=self.namespace, certificate_name=self.certificate_name)
        mock_resource.get.assert_called_with(namespace=self.namespace, name=self.certificate_name)
        self.assertEqual(result, True)