2015-04-15 3 views
1

У меня есть цикл, где я обрабатываю добавление записей в zip-файл. Я издевался над своим объектом zipfile, и я хочу поднять исключение, чтобы убедиться, что моя логика для обработки больших zip-файлов будет работать правильно.Throw exception после первого вызова

Есть ли способ с помощью MagicMocks или простых макетов принять первый вызов, но вызвать исключение на втором?

ответ

2

с генератором и Mock side_effect

from unittest.mock import Mock 

def sample_generator(): 
    yield 1 
    yield 2 
    raise Exception() 

gen = sample_generator() 

def sideeffect(): 
    global gen 
    for x in gen: 
     return x 


m = Mock(side_effect=sideeffect) 
m() #1 
m() #2 
m() #3 

вы можете получить:

File "test.py", line 22, in <module> 
    m() #3 
    .... 
    raise Exception() 
Exception 

Я уверен, что вы можете сделать его немного чище с некоторым усилием, но это должно решить основную проблему

+0

вы бог посылаете, спасибо! –

+0

стрелять, это работает, чтобы разрешить первый звонок, и бросить второй, но что, если я хочу, чтобы третий звонок был успешным? –

+0

@NathanTregillus взгляните на мой ответ, он также охватывает ваш комментарий. –

6

Самый простой способ - использовать side_effect, которые принимают либо итерируемый, вызываемый, либо исключение (класс или экземпляр)

В качестве альтернативы side_effect может быть классом или экземпляром исключения. В этом случае исключение будет возникать при вызове mock.

Как показано в Quick Guide вы можете использовать side_effect, чтобы вызвать исключение, просто

>>> mock = Mock(side_effect=KeyError('foo')) 
>>> mock() 
Traceback (most recent call last): 
... 
KeyError: 'foo' 

Более того, вы можете использовать список и исключения вместе в side_effect задания. Поэтому самый простой способ сделать то, что вам нужно, это что-то вроде этого:

>>> m = Mock(side_effect=[1, KeyError("bar"), 3]) 
>>> m("a") 
1 
>>> m("b") 
... 
KeyError: 'bar' 
>>> m("c") 
3 

Другого способа сделать это может быть использовать вызываемый писать логику как ваш макет должен реагировать. В этом случае вы можете свободно выбирать, основываясь на аргументах или состоянии вашего теста.

+0

Кто Donwvote должен оставить хотя бы комментарий! –

+0

серьезно. Ненавижу, когда люди это делают! Мне нравится ваш ответ! этот KeyError, это специальный метод? Я хочу, чтобы это бросило конкретное исключение, есть ли способ сделать это? –

+0

@NathanTregillus Я использовал KeyError как пример. Вы можете использовать любой «Исключение», которое вы хотите. –