2013-04-21 5 views
46

가져온 모듈의 함수 @patch을 이해하고 싶습니다.가져온 모듈의 함수를 조롱하는 Python

여기까지입니다.

응용 프로그램/mocking.py :

from app.my_module import get_user_name 

def test_method(): 
    return get_user_name() 

if __name__ == "__main__": 
    print "Starting Program..." 
    test_method() 

응용 프로그램/my_module/__ init__.py : mock-test.py

def get_user_name(): 
    return "Unmocked User" 

테스트/:

import unittest 
from app.mocking import test_method 

def mock_get_user(): 
    return "Mocked This Silly" 

@patch('app.my_module.get_user_name') 
class MockingTestTestCase(unittest.TestCase): 

    def test_mock_stubs(self, mock_method): 
    mock_method.return_value = 'Mocked This Silly') 
    ret = test_method() 
    self.assertEqual(ret, 'Mocked This Silly') 

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

이것은 이 아니며이 예상대로 작동합니다. "패치 된"모듈은 단순히 잠금 해제 된 값 get_user_name을 반환합니다. 테스트중인 네임 스페이스로 가져 오는 다른 패키지의 메소드를 조롱하려면 어떻게해야합니까?

+1

질문은 "모범 사례 조롱"에 관한 것이지, 아니면 당신이하고있는 것이 합리적인지 여부에 관한 것입니까? 첫 번째 부분에 대해서는 python3.3 +에 포함 된 ['Mock'] (http://www.voidspace.org.uk/python/mock/)과 같은 조롱 라이브러리를 사용한다고 말하고 싶습니다. ['unittest .mock'] (http://docs.python.org/dev/library/unittest.mock). – Bakuriu

+0

나는이 권리에 대해 갈 것인지 묻는다. 나는 모의를 보았으나이 특별한 문제를 해결할 방법이 없다. 위의 작업을 모의에서 다시 할 수있는 방법이 있습니까? – nsfyn55

답변

66

당신이 unittest.mock 패키지에서 patch 장식을 사용하는 당신은 모듈이 시험 app.mocking.get_user_name에서 네임 스페이스에 패치된다 (이 경우 app.my_module.get_user_name에서)에서 수입 된 네임 스페이스를 패치 하지 있습니다.

from mock import patch 
from app.mocking import test_method 

class MockingTestTestCase(unittest.TestCase): 

    @patch('app.mocking.get_user_name') 
    def test_mock_stubs(self, test_patch): 
     test_patch.return_value = 'Mocked This Silly' 
     ret = test_method() 
     self.assertEqual(ret, 'Mocked This Silly') 

표준 라이브러리 문서는이를 설명하는 유용한 section이 포함 Mock는 다음과 같은 것을 시도와

위를 수행합니다.

+0

내 문제가 발생합니다. 'get_user_name'은'test_method'와 다른 모듈에 있습니다. sub_module에서 무언가를 조롱하는 방법이 있습니까? 아래의 추악한 방법으로 수정했습니다. – nsfyn55

+4

'get_user_name'은'test_method'와는 다른 모듈에 있어도 상관 없습니다. 함수가 같은 이름 공간에있는'app.mocking'으로 가져 오기 때문입니다. –

+0

가 있습니다. 그래, 그 덕분에! – nsfyn55

5

Matti John의 대답이 귀하의 문제를 해결하고 (도와 주신 덕분에) 원래의 'get_user_name'기능을 조롱 한 것으로 대체하는 것이 좋습니다. 이 기능을 사용하면 기능이 교체 될 때와 그렇지 않을 때를 제어 할 수 있습니다. 또한 동일한 테스트에서 여러 번 교체 할 수 있습니다. 그렇게하기 위해서는 상당히 유사한 방식으로 '함께'문장을 사용하십시오.

+0

이것은 제기 된 질문에 중요하지 않습니다. 데코레이터 또는 컨텍스트 관리자로'patch'를 사용할 지 여부는 유스 케이스에 따라 다릅니다. 예를 들어'patch'를 데코레이터로 사용하여'xunit' 또는'pytest' 클래스의 모든 테스트에 대한 값을 모방하는 반면, 다른 경우에는 컨텍스트 관리자가 제공하는 세분화 된 컨트롤을 갖는 것이 유용합니다. – nsfyn55