Mock을 사용하여 함수 / 메소드가 호출되지 않았 음을 확인


131

Mock 라이브러리를 사용하여 응용 프로그램을 테스트하고 있지만 일부 함수가 호출되지 않았다고 주장하고 싶습니다. 모의 문서는 mock.assert_called_withand와 같은 메소드에 대해 이야기 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

이것을 달성하는 방법에 대한 아이디어가 있습니까?


@Ahmet이 그의 대답에서 지적했듯이 assert_not_called는 이제 백 포트에서도 지원됩니다 ( docs.python.org/3/library/… ).
Martin

답변:


144

이것은 귀하의 경우에 효과가 있습니다.

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

이 답변에 장고가 필요합니까? 오류가 발생했습니다 :AttributeError: MockCallable instance has no attribute 'called'
Nathan Arthur

@NathanArthur 흠, 난 후, 그렇게 생각하지 않습니다 sudo easy_install -U mockfrom mock import Mock맥 OS, 위의 실행에 차질없이. 장고 : 설치하지 마십시오
요아킴 이삭손

흠. 이상하다. Python 2.7.1을 실행 중이며 unittest from mock import Mock와 Python Mock 0.1.0을 사용하여 테스트하고 있습니다. 그 소리에 문제가 있습니까?
Nathan Arthur

다른 모듈에서 호출 가능한 클래스를 조롱하고 있으므로 module_to_test.another_module.class = mock.Mock()다른 테스트 사례 (unittest.TestCase 인스턴스)의 호출을 기억하지 못한다는 것을 확인할 수 있습니까? 나는 호출 수가이 경우에는 다시 설정하지 않습니다 생각
0xc0de

66

오래된 질문이지만 현재 mock라이브러리 (unitport.mock의 백 포트)가 assert_not_called메소드를 지원 한다는 것을 추가하고 싶습니다 .

당신을 업그레이드하십시오.

pip install mock --upgrade


29

당신은 확인할 수 called속성을, 그러나 당신의 주장이 실패 할 경우, 당신이 알고 싶을 것이다 다음 것은 뭔가 에 대한 정보가 처음부터 표시하는 당신은뿐만 아니라 준비 할 수 있도록 예상치 못한 통화. 를 사용하면 대신 unittest내용을 확인할 수 있습니다 call_args_list.

self.assertItemsEqual(my_var.call_args_list, [])

실패하면 다음과 같은 메시지가 나타납니다.

AssertionError : 요소 개수가 같지 않았습니다.
첫 번째는 0, 두 번째는 1 : call ( 'first argument', 4)

14

클래스를 사용하여 테스트 할 때 unittest.TestCase 를 상속하면 다음 과 같은 메소드를 사용할 수 있습니다.

  • assertTrue
  • 주장하다
  • assertEqual

그리고 비슷한 ( 파이썬 문서에서) 에서 나머지를 찾으십시오).

귀하의 예제에서 우리는 mock_method.called 속성이 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))

11

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


1

다른 답변으로 판단하면 @ rob-kennedy 이외의 사람 은call_args_list .

그것은 당신이 정확히 반대를 구현할 수있는 강력한 도구입니다 MagicMock.assert_called_with()

call_args_listcall객체 의 목록입니다 . 각 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하고 다른 값이 아닌 특정 값에서 호출되었는지 테스트 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.