>  기사  >  백엔드 개발  >  Python 클래스 모의

Python 클래스 모의

王林
王林원래의
2024-08-28 18:32:30364검색

Mocking Python Classes

최근에는 Python 모듈용 Pytest를 사용하여 단위 테스트를 작성해야 했습니다. 모듈에는 생성자 내에서 다른 클래스가 초기화되는 클래스가 포함되어 있습니다.

평소처럼 저는 각 클래스 메서드에 대한 테스트를 쉽게 작성할 수 있도록 이 클래스에 대한 Fixture를 만들었습니다. 이 시점에서 생성자에서 시작된 다양한 클래스를 모의하려고 할 때 몇 가지 문제에 부딪혔습니다. 조롱이 작동하지 않았고 이러한 클래스의 인스턴스가 계속 생성되고 있었습니다.

온라인에서 찾은 몇 가지 솔루션을 조사하고 결합한 후 어떻게 수업을 모의할 수 있었는지 공유하고 싶습니다.

해결책

다음은 제가 조롱하려고 했던 클래스의 예입니다.

class ClassA:
    def __init__(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0

테스트 중에 이 클래스의 모든 필드에 값을 설정하고 싶습니다. 이 값은 None 또는 클래스 모의일 수 있지만 ClassB 및 ClassC 클래스의 시작을 원하지 않습니다.

우리의 경우 self.class_b와 self.class_c가 모의 객체여야 한다고 결정해 보겠습니다.

@pytest.fixture
def mock_class_b():
    class_b = Mock(spec=ClassB)
    return class_b

@pytest.fixture
def mock_class_c():
    class_c = Mock(spec=ClassC)
    return class_c

따라서 우리의 목표를 달성하는 이 클래스의 설비는 다음과 같습니다.

@pytest.fixture
def class_a_mock(mock_class_b, mock_class_c):
    with patch.object(target=ClassA, attribute="__init__", return_value=None) as mock_init:
        class_a = ClassA()
        class_a.class_b = mock_class_b
        class_a.class_c = mock_class_c
        class_b.count = 0
        return class_a

중요한 부분은 Python의 unittest.mock 모듈에 있는 patch.object 함수를 사용하는 방법입니다. 테스트에서 주어진 객체의 속성을 모의 값이나 다른 값으로 일시적으로 바꾸는 데 사용됩니다.

인수

  1. target=ClassA: 속성을 패치하려는 객체(일반적으로 클래스)입니다.
  2. attribute="__init__": 패치하려는 속성의 이름.
  3. return_value=None: __init__ 메소드를 아무것도 하지 않는 함수로 대체

이런 방법으로 픽스쳐에 모의 변수를 생성할 수 있습니다.
patch.object에 대해 자세히 알아보세요

테스트 팁

나는 어떤 이유로든 클래스 A의 코드를 변경할 수 없는 이런 종류의 경우를 위해 이 튜토리얼을 작성했습니다. 그러나 일반적으로 로직을 변경하기보다는 테스트 가능성을 높이기 위해 가능하다면 코드를 수정하는 것이 좋습니다. .

다음은 클래스 A를 보다 쉽게 ​​테스트할 수 있도록 수정하는 방법에 대한 몇 가지 예입니다.

옵션 1: 클래스 B와 클래스 C의 인스턴스를 매개변수로 전달합니다.
이렇게 하면 픽스쳐를 작성할 때 인스턴스 대신 모의 객체를 전달할 수 있습니다.

class ClassA:
    def __init__(self, class_b_instance, class_c_instance):
        self.class_b = class_b_instance
        self.class_c = class_c_instance
        self.count = 0

옵션 2: 테스트 모드를 나타내는 부울 변수를 생성합니다.
이렇게 하면 클래스 A의 어떤 필드가 시작될 때 값을 얻을지 여부를 결정할 수 있습니다.

class ClassA:
    def __init__(self, test_mode=False):
        if not test_mode:
            self.class_b = ClassB()
            self.class_c = ClassC()
        self.count = 0

옵션 3: 별도의 방법으로 수업을 시작하세요.
이 접근 방식을 사용하면 테스트 모듈에서 set_class_variables 호출을 피할 수 있습니다.

class ClassA:
    def __init__(self):
        self.class_b = None
        self.class_c = None
        self.count = None

    def set_class_variables(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0

도움이 되었기를 바랍니다! :)

위 내용은 Python 클래스 모의의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.