2014-01-27 4 views
1

모의 메서드 인수 일치 및 인수 캡처를 수행하는 동안 파이썬 외부 종속성을 조롱하는 방법을 이해하려고합니다.인수 일치, 파이썬에서 캡처하는 방법

1) 인수 일치 :

class ExternalDep(object): 
    def do_heavy_calc(self, anInput): 
     return 3 

class Client(object): 
    def __init__(self, aDep): 
     self._dep = aDep 

    def invokeMe(self, aStrVal): 
     sum = self._dep.do_heavy_calc(aStrVal) 
     aNewStrVal = 'new_' + aStrVal 
     sum += self._dep.do_heavy_calc(aNewStrVal) 

class ClientTest(unittest.TestCase): 
    self.mockDep = MagicMock(name='mockExternalDep', spec_set=ExternalDep) 
    ### 
    self.mockDep.do_heavy_calc.return_value = 5 
    ### this will be called twice regardless of what parameters are used 
    ### in mockito-python, it is possible to create two diff mocks (by param),like 
    ### 
    ### when(self.mockDep).do_heavy_calc('A').thenReturn(7) 
    ### when(self.mockDep).do_heavy_calc('new_A').thenReturn(11) 
    ### 
    ### QUESTION: how could I archive the same result in MagicMock? 

    def setUp(self): 
     self.cut = Client(self.mockDep) 

    def test_invokeMe(self): 
     capturedResult = self.cut.invokeMe('A') 
     self.assertEqual(capturedResult, 10, 'Unexpected sum') 
     # self.assertEqual(capturedResult, 18, 'Two Stubs did not execute') 

나는 다음과 같은 조롱 시나리오 수용 할 수도 MagicMock 또는 mockito - 파이썬에 대한 좋은 문서 또는 예를 찾을 수 없습니다 캡처 2) 인수 :

class ExternalDep(object): 
    def save_out(self, anInput): 
     return 17 

class Client(object): 
    def __init__(self, aDep): 
     self._dep = aDep 

    def create(self, aStrVal): 
     aNewStrVal = 'new_' + aStrVal if aStrVal.startswith('a') 
     self._dep.save_out(aNewStrVal) 

class ClientTest(unittest.TestCase): 
    self.mockDep = MagicMock(name='mockExternalDep', spec_set=ExternalDep) 
    ### 
    self.mockDep.save_out.return_value = 5 
    ### this will be called with SOME value BUT how can I capture it? 
    ### mockito-python does not seem to provide an answer to this situation either 
    ### (unline its Java counterpart with ArgumentCaptor capability) 
    ### 
    ### Looking for something conceptually like this (using MagicMock): 
    ### self.mockDep.save_out.argCapture(basestring).return_value = 11 
    ### 
    ### QUESTION: how could I capture value of parameters with which 
    ### 'save_out' is invoked in MagicMock? 

    def setUp(self): 
     self.cut = Client(self.mockDep) 

    def test_create(self): 
     capturedResult = self.cut.create('Z') 
     self.assertEqual(capturedResult, 5, 'Unexpected sum') 

     ### now argument will be of different value but we cannot assert on what it is 
     capturedResult = self.cut.create('a') 
     self.assertEqual(capturedResult, 5, 'Unexpected sum') 

을 누구든지 MagicMock을 사용하여이 두 모의 시나리오를 수행하는 방법을 보여줄 수 있다면 매우 감사 할 것입니다. (무엇인가 불분명한지 물어보십시오.)

+1

"인수 일치"란 무엇을 의미합니까? * 조롱 *과 어떤 관련이 있습니까? – Bakuriu

답변

1

assert_called_with을 Matcher와 함께 사용하는 것이 도움이 될 수 있습니다. 이렇게하면 통화에서 인수에 더 세밀하게 액세스 할 수 있습니다. 예 :

>>> def compare(self, other): 
...  if not type(self) == type(other): 
...   return False 
...  if self.a != other.a: 
...   return False 
...  if self.b != other.b: 
...   return False 
...  return True 

>>> class Matcher(object): 
     def __init__(self, compare, some_obj): 
      self.compare = compare 
      self.some_obj = some_obj 
     def __eq__(self, other): 
      return self.compare(self.some_obj, other) 

>>> match_foo = Matcher(compare, Foo(1, 2)) 
>>> mock.assert_called_with(match_foo) 
+0

matchers를 직접 쓰고 싶지 않다면 이미 출시 된 라이브러리를 사용해 볼 수 있습니다. https://github.com/Xion/callee – Xion

관련 문제