2014-12-03 2 views
1

Структура моих модулей:патча несколько методов из различных модулей (с использованием Python издеваться)

foo: 
    - load() # from DB 


bar: 
    - check() # with user 
    - take_action() 

Я хочу проверить take_action (которые в основном загружают значения и проверяет с пользователем, прежде чем принимать меры) по насмешливому как нагрузкам и проверить.

Вот издевается:

mock_load = Mock(side_effects=[<>, <>, <>]) # different data sets 
mock_check = Mock(return_value=True) # User approval 

Как использовать patch.multiple для достижения этой цели? не

with patch.multiple(??): 
    # proceed to test 
    take_action 
+0

python (2.6) (--------) –

ответ

5

Короткий ответ: нет, вы не можете использовать patch.multiple(), чтобы сделать это. Как описано в patch.multiple, все аргументы будут применены ко всем созданным mocks, и все аргументы ДОЛЖНЫ быть атрибутом одного и того же объекта. Вы ДОЛЖНЫ сделать это один раз за один раз.

К сожалению, вы используете Python 2.6, так что вы можете использовать только nested FRON contextlib, как указал в python: create a "with" block on several context managers и Multiple context `with` statement in Python 2.6.

Может быть, более чистый и простой способ сделать это заключается в использовании @patch в качестве декоратора:

@patch("foo.load",side_effects=["a","b","c"]) 
@patch("bar.check",return_value=True) 
def test_mytest(mock_check,mock_load): 
    take_action() 
    assert mock_load.called 
    assert mock_check.called 

Если вам это нужно во всех тестах тестового класса вы можете украсить класс и использовать издевается во всех испытаниях методы:

@patch("foo.load",side_effects=["a","b","c"]) 
@patch("bar.check",return_value=True) 
class TestMyTest(unittest.TestCase) 
    def test_mytestA(self,mock_check,mock_load): 
     take_action() 
     self.assertTrue(mock_load.called) 
     self.assertTrue(mock_check.called) 

    def test_mytestA(self,mock_check,mock_load): 
     mock_check.return_value = False 
     take_action() 
     self.assertTrue(mock_load.called) 
     self.assertTrue(mock_check.called) 

Наконец, вы можете сделать это с помощью with и contextlib и первый пример стал:

from contextlib import nested 

with nested(patch("foo.load",side_effects=["a","b","c"]), patch("bar.check",return_value=True)) as (mock_load, mock_check): 
    take_action() 
    assert mock_load.called 
    assert mock_check.called 

... Или гнездо его вручную ....

with patch("foo.load",side_effects=["a","b","c"]) as mock_load: 
    with patch("bar.check",return_value=True)) as mock_check: 
     take_action() 
     assert mock_load.called 
     assert mock_check.called 

Моих ощущения, что декораторы являются наиболее читаемыми и простыми в использовании.