2012-09-27 4 views
4

내 파이썬 기능을 테스트하기 위해 os.listdir 패치와 다른 os 함수를 패치해야합니다. 그러나 패치를 적용하면 import 문이 실패합니다. 이 함수를 실제로 하나의 모듈 안에 패치 할 수 있습니까? 그리고 tests.py는 정상적으로 작동합니까?하나의 모듈에 대해서만 모의 기능을 패치 하시겠습니까?

import os 
from mock import patch 

# when both isdir and isfile are patched 
# the function crashes 
@patch('os.path.isdir', return_value=False) 
@patch('os.path.isfile', return_value=False) 
def test(*args): 
    import ipdb; ipdb.set_trace() 
    real_function(some_arguments) 
    pass 

test() 

내가 real_function이 패치 os.path을보고 싶어하고, 시험은 정상적인 기능을 볼 수 :

여기 import 나누기 예입니다.

here's the traceback

답변

4

당신은 컨텍스트 관리자로 patch을 사용할 수 있습니다, 그래서 그것은 단지 with 문 내부의 코드에 적용됩니다

import os 
from mock import patch 

def test(*args): 
    import ipdb; ipdb.set_trace() 
    with patch('os.path.isdir', return_value=False): 
     with patch('os.path.isfile', return_value=False): 
      real_function(some_arguments) 
    pass 

test() 
+0

좋은 생각입니다. 사실, 나는 자신의 컨텍스트 매니저를 만들 수 있습니다. –

0

은 아래 당신이 필요로 작동합니다. 모든 것이 올바른 상태로 반환되었음을 보여주기 위해 테스트 실행 전후에 os.listdir을 출력합니다.

import unittest, os 
from unittest import TestLoader, TextTestRunner 

def tested_func(path): 
    return os.listdir(path * 2) 

class Example(unittest.TestCase): 

    def setUp(self): 
     self._listdir = os.listdir 
     os.listdir = lambda p: ['a', 'b', 'a', 'b'] 

    def test_tested_func(self): 
     self.assertEqual(tested_func('some_path'), ['a', 'b', 'a', 'b']) 

    def tearDown(self): 
     os.listdir = self._listdir 

print os.listdir 
TextTestRunner().run(TestLoader().loadTestsFromTestCase(Example)) 
print os.listdir 
+0

는 당신이 제공하는 모의 모듈의 간단한 아날로그이며, 그것은하지 않습니다 주된 문제를 해결하십시오 : os.listdir은 다른 코드에서도 패치되고 임포트는 실패합니다. –

0

패치는 테스트 메소드 또는 테스트 클래스에서 데코레이터로 사용할 수 있습니다. 아주 깨끗한 코드를 만듭니다. 패치 된 개체가 테스트 메서드로 전달됩니다. 테스트 클래스 수준에서 똑같은 작업을 수행 할 수 있으며 모의 객체는 모든 테스트 메소드에 전달됩니다. 이 경우 setUp 또는 tearDown은 모두 자동으로 처리되므로 사용하지 않아도됩니다.

# module.py 
import os 

def tested_func(path): 
    return os.listdir(path * 2) 


# test.py 
from mock import patch 

@patch('module.os.listdir') 
def test_tested_func(self, mock_listdir): 
    mock_listdir.return_value = ['a', 'b'] 

    self.assertEqual(tested_func('some_path'), ['a', 'b', 'a', 'b']) 
    mock_listdir.assert_called_with('some_path' * 2) 

실제로 테스트 할 모듈에서 패치하려는 기능을 조롱하는 것에주의하십시오.

+0

패치 된 코드에서 패치 파일 os 파일 시스템 기능 블록 가져 오기가 실패했습니다. –

+0

코드를 더 게시 할 수 있습니까? 실제 위반 사례입니까? 왜냐하면 당신이 준 예제에서 이것이 작동하지 않을 것이기 때문입니다. 시도하고 문제를 찾기를 좋아할 것입니다. – aychedee

+0

그리고 추적은 흥미로울 것입니다 – aychedee

0

당신은뿐만 아니라 "수",하지만 당신은 그 http://mock.readthedocs.org/en/latest/patch.html#where-to-patch

추신을 "해야"당신이, 내가 라이브러리 http://mockstar.readthedocs.org/를 사용하는 것이 좋습니다 패치하려는 기기의 side_effects을 설명하기 위해 더 "선언"의 방법을 수행 할 경우

+0

나는 이것을 읽고 시험해 보았다. 이름으로 함수를 로컬 네임 스페이스에 가져 왔지만 패치 후 가져 오기가 실패합니다. –