code

함수/메소드가 Mock을 사용하여 호출되지 않았음을 주장합니다.

starcafe 2023. 7. 17. 21:17
반응형

함수/메소드가 Mock을 사용하여 호출되지 않았음을 주장합니다.

Mock 라이브러리를 사용하여 응용 프로그램을 테스트하고 있지만 일부 기능이 호출되지 않았음을 확인하고 싶습니다.모의 문서는 다음과 같은 방법에 대해 말합니다.mock.assert_called_with그리고.mock.assert_called_once_with하지만 저는 그런 것을 발견하지 못했습니다.mock.assert_not_called또는 모의 검증과 관련된 것이 호출되지 않았습니다.

저는 다음과 같은 것으로 갈 수 있지만, 그것은 멋지지도 않고 비단결처럼 보이지도 않습니다.

def test_something:
    # some actions
    with patch('something') as my_var:
        try:
            # args are not important. func should never be called in this test
            my_var.assert_called_with(some, args)
        except AssertionError:
            pass  # this error being raised means it's ok
    # other stuff

어떻게 해야 할지 생각나는 거 있어요?

이것은 당신의 경우에 효과가 있을 것입니다.

assert not my_var.called, 'method should not have been called'

샘플;

>>> mock=Mock()
>>> mock.a()
<Mock name='mock.a()' id='4349129872'>
>>> assert not mock.b.called, 'b was called and should not have been'
>>> assert not mock.a.called, 'a was called and should not have been'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: a was called and should not have been

오래된 질문이지만, 저는 현재 그것을 추가하고 싶습니다.mock라이브러리(unittest.backport) 지원assert_not_called방법.

업그레이드만 하면 됩니다.

pip install mock --upgrade

와 함께python >= 3.5사용할 수 있습니다.mock_object.assert_not_called().

다음을 확인할 수 있습니다.called속성. 그러나 어설션이 실패할 경우 다음으로 알고 싶은 것은 예기치 않은 호출에 대한 이므로 해당 정보가 처음부터 표시되도록 조정하는 것이 좋습니다.사용.unittest의 내용을 확인할 수 있습니다.call_args_list대신:

self.assertItemsEqual(my_var.call_args_list, [])

오류가 발생하면 다음과 같은 메시지가 표시됩니다.

AssertionError: 요소 수가 같지 않습니다.
첫 번째는 0, 두 번째는 1: 호출('첫 번째 인수', 4)

클래스를 사용하여 테스트하는 경우 단위 테스트를 상속합니다.TestCase는 다음과 같은 방법을 사용할 수 있습니다.

  • 참임 주장
  • assertificate
  • 평등을 주장합니다.

및 유사합니다(파이썬 설명서에서 나머지를 확인할 수 있습니다.

이 예제에서는 mock_method.called property가 False이면 메서드가 호출되지 않았다고 간단히 주장할 수 있습니다.

import unittest
from unittest import mock

import my_module

class A(unittest.TestCase):
    def setUp(self):
        self.message = "Method should not be called. Called {times} times!"

    @mock.patch("my_module.method_to_mock")
    def test(self, mock_method):
        my_module.method_to_mock()

        self.assertFalse(mock_method.called,
                         self.message.format(times=mock_method.call_count))

다른 답변들로 미루어 볼 때, @rob-kennedy를 제외하고는 아무도 그에 대해 이야기하지 않았습니다.call_args_list.

이것은 바로 그 반대의 것을 구현할 수 있는 강력한 도구입니다.MagicMock.assert_called_with()

call_args_list의 목록입니다.call물건들.각각call개체는 모조된 호출 케이블에 대해 수행된 호출을 나타냅니다.

>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m.call_args_list
[]
>>> m(42)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42)]
>>> m(42, 30)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42), call(42, 30)]

사용call첫 번째 구성 요소는 관련 호출의 모든 위치 인수를 포함하는 튜플이고 두 번째 구성 요소는 키워드 인수 사전인 길이 2의 튜플과 비교할 수 있기 때문에 개체는 쉽습니다.

>>> ((42,),) in m.call_args_list
True
>>> m(42, foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((42,), {'foo': 'bar'}) in m.call_args_list
True
>>> m(foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((), {'foo': 'bar'}) in m.call_args_list
True

따라서 OP의 구체적인 문제를 해결하는 방법은

def test_something():
    with patch('something') as my_var:
        assert ((some, args),) not in my_var.call_args_list

이 방법은 조롱당한 콜이 호출되었는지 확인하는 대신 다음을 통해MagicMock.called이제 특정 인수 집합으로 호출되었는지 확인할 수 있습니다.

그거 유용하네요.목록을 가져오는 함수를 테스트하고 다른 함수를 호출한다고 가정합니다.compute()목록의 각 값이 특정 조건을 만족하는 경우에만 해당됩니다.

이제 조롱할 수 있습니다.compute어떤 값에서는 호출되었지만 다른 값에서는 호출되지 않았는지 테스트합니다.

제가 선호하는 모의 호출/불호 확인 관용구는 다음과 같습니다.self.assertEqual(post_mock.call_count, 0)

이점:

  1. 모의고사가 정확한 횟수만큼 호출되었는지 확인합니다.
  2. 내부 PyTest를 사용하여 동등한 기능을 주장합니다.

언급URL : https://stackoverflow.com/questions/12187122/assert-a-function-method-was-not-called-using-mock

반응형