파이썬 모의 가져오기

Abid Ullah 2023년6월21일
  1. 파이썬 모의 가져오기
  2. Python에서 조롱의 일반적인 함정
  3. Python에서 Mock의 기본 사용법
  4. Python 모의 가져오기를 사용하는 방법
  5. 테스트에서 Python 종속성
  6. 파이썬 mock 객체
파이썬 모의 가져오기

이 Python 기사에서는 mock 라이브러리를 살펴보고 효과적으로 사용하는 방법을 배웁니다. 간단한 예제로 시작한 다음 고급 사용법을 살펴보겠습니다.

우리는 mock객체와 조롱의 사용법과 함정을 배웁니다.

파이썬 모의 가져오기

Python의 mock 라이브러리는 단위 테스트에 가장 많이 사용되는 라이브러리 중 하나입니다. 이를 통해 시스템의 일부를 모의 개체로 교체하고 예상대로 사용한다고 주장할 수 있습니다.

조롱은 강력한 도구이지만 종종 오해를 받습니다. 이 기사에서는 조롱이 무엇인지, 어떻게 사용할 수 있는지, 몇 가지 일반적인 위험에 대해 설명합니다.

파이썬에서 조롱하기

모킹은 실제 객체를 가짜 객체로 바꾸는 과정입니다. 가짜 개체를 mock이라고 합니다.

Mocking을 사용하면 실제로 다른 부분에 의존하지 않고 코드가 시스템의 다른 부분과 상호 작용하는 방식을 테스트할 수 있습니다. 예를 들어 데이터베이스가 없어도 코드가 데이터베이스와 상호 작용하는 방식을 테스트하기 위해 데이터베이스를 모의할 수 있습니다.

Python에서 Mock을 사용하는 방법

조롱은 두 가지 다른 목적으로 사용될 수 있습니다.

  1. 코드의 동작을 테스트하기 위해

    예를 들어 데이터베이스를 모의하여 코드가 데이터베이스를 올바르게 쿼리하고 있다고 주장할 수 있습니다.

  2. 테스트하고 싶지 않은 동작을 제거하기 위해

    예를 들어 연결을 피하기 위해 데이터베이스를 조롱할 수 있습니다.

조롱을 사용하는 목적에 따라 사용 방법이 결정됩니다.

테스트 동작

모킹을 사용하여 동작을 테스트할 때 코드가 예상대로 모의 개체와 상호 작용하는지 확인하려고 합니다. 모의 개체는 실제 개체와 동일한 인터페이스를 가져야 코드에서 모의 개체인지 알 수 없습니다.

assert_called_with() 메서드를 사용하여 모의 메서드가 예상 인수로 호출되었음을 확인할 수 있습니다. 예를 들어 데이터베이스를 조롱하는 경우 query() 메서드가 올바른 SQL로 호출되었다고 주장할 수 있습니다.

모의 메서드가 호출되었음을 어설션하기 위해 assert_called() 메서드를 사용할 수도 있습니다. 이는 인수에 대해 신경 쓰지 않거나 인수가 복잡하고 주장하기 어려운 경우에 유용합니다.

스터빙 아웃 동작

모킹을 사용하여 동작을 제거할 때 예상한 값을 반환하도록 모의 개체를 구성하려고 합니다. 예를 들어 데이터베이스를 조롱하는 경우 더미 데이터 목록을 반환하도록 query() 메서드를 구성할 수 있습니다.

side_effect 속성을 사용하여 목 객체를 구성할 수 있습니다. side_effect는 함수를 포함한 모든 값이 될 수 있습니다.

모의 객체가 호출되면 side_effect가 반환됩니다.

예를 들어 side_effect를 사용하여 모의 객체가 호출될 때마다 다른 값을 반환할 수 있습니다. 이는 오류나 다른 동작을 시뮬레이션하는 데 유용합니다.

예외를 발생시키기 위해 side_effect를 사용할 수도 있습니다. 이는 오류를 시뮬레이션하는 데 유용합니다.

Python에서 조롱의 일반적인 함정

조롱을 사용할 때 몇 가지 일반적인 함정이 있습니다.

  1. 한 가지 함정은 너무 많이 조롱하려는 것입니다. 조롱은 강력한 도구이지만 만병통치약은 아닙니다.

    모의는 전체 시스템의 동작이 아니라 코드의 동작을 테스트할 때 가장 유용합니다.

    모의를 너무 많이 시도하면 모의 개체가 많아지고 테스트를 유지 관리하기가 어려워집니다. 필요한 객체만 조롱하고 나머지는 실제 객체를 사용하는 것이 좋습니다.

  2. 또 다른 함정은 적절하지 않을 때 조롱을 사용하는 것입니다. 모킹은 코드의 격리된 부분을 테스트할 때 가장 유용합니다.

    전체 시스템을 테스트하는 경우 일반적으로 통합 테스트를 사용하는 것이 좋습니다. 통합 테스트는 전체 시스템을 실행하는 테스트이며 실행하는 데 더 느리고 비용이 더 많이 들지만 더 정확합니다.

  3. 마지막으로 일반적인 실수는 가짜를 사용해야 할 때 모의를 사용하는 것입니다. 가짜 개체는 실제 개체를 모방하지만 동일한 인터페이스를 갖지 않는 개체입니다.

예를 들어 가짜 데이터베이스는 실제 데이터베이스에 연결하는 대신 하드 코딩된 데이터를 반환할 수 있습니다. 가짜는 동작을 확인하는 데 도움이 되지만 동작을 테스트하는 데는 유용하지 않습니다.

Python에서 Mock의 기본 사용법

모의 객체의 가장 기본적인 용도는 객체를 모의 객체로 대체하는 것입니다.

예를 들어, 객체를 인자로 받아 그것으로 무언가를 하는 함수가 있다고 합시다. 개체의 이름을 인쇄할 수도 있습니다.

예제 코드:

def print_name(obj):
    print(obj.name)

이 함수를 테스트하고 싶다면 name 속성을 가진 객체를 생성하고 함수에 전달할 수 있습니다.

예제 코드:

class TestObject:
    def __init__(self, name):
        self.name = name


obj = TestObject("Abid")
print_name(obj)

출력:

Abid

코드가 작동하고 Abid로 인쇄된 이름을 볼 수 있습니다. 그러나 몇 가지 단점이 있습니다.

첫째, 테스트를 위한 실제 객체를 생성해야 합니다. 이 간단한 예에서는 큰 문제가 아닐 수 있지만 더 복잡한 시스템에서는 테스트용으로 필요한 개체를 설정하는 데 많은 작업이 필요할 수 있습니다.

둘째, 이 접근 방식은 그다지 유연하지 않습니다. 다른 동작을 테스트하려면 매번 새로운 실제 개체를 만들어야 합니다.

예를 들어 객체에 이름 속성이 없을 때 어떤 일이 발생하는지 테스트하려면 어떻게 해야 할까요?

예제 코드:

class TestObject:
    def __init__(self, name):
        self.name = name


obj = TestObject()
print_name(obj)

실제 개체를 사용하면 오류가 발생합니다. 그러나 테스트 개체를 사용하면 코드의 출력이 코드에서 누락된 것입니다.

출력:

__init__() missing 1 required positional argument: 'name'

Python 모의 가져오기를 사용하는 방법

테스트 목적으로 모의 가져오기를 사용하려면 모의 개체를 만들고 살펴보겠습니다.

먼저 mock 라이브러리를 가져와야 합니다. mock 라이브러리는 목 객체를 만들 수 있는 mock 클래스를 제공합니다.

라이브러리를 가져온 후 mock 클래스를 호출하고 인쇄하여 이 모의 개체가 어떻게 보이는지 확인합니다.

예제 코드:

from unittest.mock import Mock

mock = Mock()
print(mock)

출력:

<Mock id='139754809551888'>

코드의 출력은 ID id='139754809551888' 문자열이 있는 모의 객체의 표현을 보여줍니다.

이제 이 모의 개체로 무엇을 할 수 있고 어떻게 사용할 수 있는지 살펴보겠습니다. 음, 목 객체는 일반적으로 코드에서 다른 객체를 패치하는 데 사용됩니다.

패치라고 하면 교체, 모방 또는 모방을 의미합니다. 그들은 모두 동일합니다.

조롱의 본질은 가능한 한 실제에 가까운 것을 대체하는 것임을 기억하십시오. 또한 모의 테스트를 실행할 때 제어된 환경에 있어야 한다는 점을 기억하십시오.

따라서 외부 품위가 모의 테스트를 실패하게 만들지는 않습니다.

코드에 외부 종속성이 있다고 가정해 보겠습니다. 외부 종속성의 예로 json을 사용하겠습니다.

그리고 제어하기 어렵고 테스트에서 반드시 발생하고 싶지 않은 동작이 있습니다.

우리가 할 수 있는 것은 모의 개체를 사용하여 이 종속성을 패치하는 것입니다. 따라서 먼저 json 파일 형식을 가져와야 합니다.

그런 다음 JSON의 json.dumps 메서드를 사용하고 사전을 연결합니다. 따라서 우리는 외부 종속성 메서드의 메서드를 사용하고 있습니다.

그런 다음 json = mock을 사용하여 JSON을 패치하고 mock 개체에는 dumbs 개체가 없습니다. 이를 증명하기 위해 json 디렉토리를 인쇄해야 합니다.

예제 코드:

import json

data = json.dumps({"a": 1})
json = mock
print(dir(json))

출력:

['assert_any_call', 'assert_called', 'assert_called_once', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'assert_not_called', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'dumps', 'getdoc', 'method_calls', 'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value', 'side_effect']

모의 객체와 관련된 출력으로 객체 및 메서드의 문자열을 볼 수 있습니다. 그리고 dumps는 코드 출력의 메서드 중 하나가 아닙니다.

테스트에서 Python 종속성

단위 테스트를 작성하는 함수가 request 모듈 또는 날짜 시간과 같은 종속성을 사용하는 경우. 그런 다음 단위 테스트가 테스트 중인 함수에서 항상 동일한 출력을 얻지 못할 가능성이 있습니다.

request 라이브러리를 사용하고 일부 HTTP 요청을 만드는 함수가 있다고 가정해 보겠습니다. 이제 인터넷 연결 없이 단위 테스트를 실행하면 실패하고 request 라이브러리에서 연결 오류가 발생합니다.

그렇기 때문에 제어된 환경에서 코드를 테스트하여 예측할 수 없는 종속성에 대한 제어를 얻는 것이 좋습니다. 여기서 종속성에 대한 실제 호출을 모의 객체로 대체할 수 있습니다. 그러면 해당 종속성의 동작을 조정할 수 있습니다.

예를 들어 실제 HTTP 요청을 하는 대신 request.get() 함수를 호출하면 반환되는 더미 HTTP 응답을 제공할 수 있습니다.

모의 개체에는 볼 수 있는 사용자에 대한 정보가 있기 때문에 종속성도 스푸핑됩니다.

예를 들어 호출한 경우 몇 번 호출했습니까? 또는 특정 종속성을 몇 번 호출했습니까? 따라서 이것은 더 강력한 단위 테스트를 작성하는 데 도움이 될 수 있습니다.

이제 테스트를 위해 Python에서 개체를 모의하는 방법을 살펴보겠습니다.

파이썬 mock 객체

우리는 Python 모의 개체를 더 잘 이해하기 위해 두 개의 Python 스크립트에서 작업할 것입니다.

  1. 롤_주사위_기능
  2. roll_dice_function 모의

따라서 임의의 값을 생성하는 코드를 작업할 것입니다. 숫자와 다른 숫자 사이의 정수를 반환하는 간단한 roll_dice_function이 있습니다.

그리고 roll_dice_function 함수에 두 숫자를 모두 제공합니다.

예제 코드:

# import library
import random

# define function


def roll_dice_function():
    print("The number is....")
    return random.randint(5, 10)

따라서 먼저 라이브러리를 가져옵니다. 그런 다음 def 키워드를 사용하여 함수를 정의합니다.

이 함수는 5에서 10 사이의 정수를 반환합니다. random 모듈의 random.randint 기능을 사용합니다.

roll_dice_function 코드 작업을 마치면 모의 개체를 사용하여 roll_dice_function을 테스트하는 다른 코드를 작성합니다. 계속합시다.

먼저 mock에 대한 테스트 라이브러리를 가져와야 합니다.

# import library
from unittest.mock import Mock
import random

# define function


def roll_dice_function():
    print("The number is....")
    return random.randint(5, 10)

어떻게 작동하는지 봅시다. 이제 우리는 이전에 생성한 roll_dice_function의 기능을 고려할 것입니다.

따라서 함수를 호출할 때마다 5에서 10까지의 난수를 얻습니다.

예제 코드:

# import library
from unittest.mock import Mock
import random

# define function


def roll_dice_function():
    print("The number is....")
    return random.randint(5, 10)


roll_dice_function()

출력:

The number is....
7

코드를 다시 실행하고 이번에는 어떤 숫자가 나오는지 봅시다.

출력:

The number is....
5

따라서 함수를 호출할 때마다 5에서 10 사이의 임의의 숫자가 생성됩니다.

이제 mock을 사용하여 호출할 때마다 함수가 동일한 값을 반환하도록 합니다.

mock 객체 생성

mock 객체를 생성하려면 mock 라이브러리에 정의된 mock 클래스 객체를 생성해야 합니다.

예제 코드:

mock_roll_object = mock.Mock()

이제 모의 객체를 mock_roll_object라고 부를 것입니다.

mock_roll_object = mock.Mock()
mock_roll_object

출력:

<Mock name='mock.Mock()' id='139883130268416'>

모의 개체를 호출하면 모의 개체로 출력을 얻을 수 있음을 보여줍니다. 이것이 일반적으로 목 객체에 관한 것입니다. 모의 개체를 호출할 때마다 모의 개체를 출력으로 얻습니다.

단순화하기 위해 모의 개체에서 몇 가지를 정의할 수 있습니다. 디버깅 목적으로 이름을 정의할 수 있습니다.

예제 코드:

mock_roll_object = mock.Mock(name="mocking roll dice")

따라서 단위 테스트를 디버깅하려고 하면 해당 이름이 표시되어 디버깅에 도움이 될 수 있습니다.

출력:

<Mock name='mocking roll dice' id='139883130347136'>

여기서 우리 모의 이름은 모킹 롤 다이스입니다.

이제 특정 값을 반환하려면 return_value에 값을 할당해야 합니다. 따라서 모의 개체를 호출할 때마다 동일한 번호를 얻게 됩니다.

예제 코드:

mock_roll_object = mock.Mock(name="mocking roll dice", return_value=8)

이제 객체를 호출하겠습니다.

mock_roll_object()

출력:

8

모의 개체를 호출할 때마다 8을 얻습니다. return_value에 8을 할당했기 때문에 동일한 반환 값을 얻게 됩니다.

이 Python 문서가 Python에서 Mock을 사용하는 방법을 이해하는 데 도움이 되기를 바랍니다.

작가: Abid Ullah
Abid Ullah avatar Abid Ullah avatar

My name is Abid Ullah, and I am a software engineer. I love writing articles on programming, and my favorite topics are Python, PHP, JavaScript, and Linux. I tend to provide solutions to people in programming problems through my articles. I believe that I can bring a lot to you with my skills, experience, and qualification in technical writing.

LinkedIn

관련 문장 - Python Mock