2014-10-12 2 views
1

Рассмотрим следующий простой код:программный модуль уровня выполнения дважды при обновлении

test_code.py

def f(): 
    return 'unpatched' 

import patch_stuff 

patch_stuff.patch_it_up() 
print f() 

patch_stuff.py

from mock import patch 

def patch_it_up(): 
    p = patch('test_code.f') 
    m = p.start() 
    m.return_value = 'patched' 

Я бы ожидать выход бег python test_code.py будет

patched 

однако выход:

unpatched 
patched 

Каким образом?

ответ

1

В коде есть две проблемы. Сначала файл test_code.py вызывается дважды - сначала, когда вы его вызываете, а затем снова, когда mock импортирует его для создания патча. Таким образом, вы должны изменить его следующим образом:

def f(): 
    return 'unpatched' 

import patch_stuff 

if __name__ == "__main__": 
    patch_stuff.patch_it_up() 
    print f() 

Это будет печатать только 'unpatched' строку. Что приводит ко второму: the documentation предполагает, что это не то, как работают патчеры. Когда вы вызываете метод start, он возвращает исправленный объект, который будет использоваться. Таким образом, ожидаемый результат может быть достигнут со следующими изменениями:

patch_stuff.py

from mock import patch 

def patch_it_up(): 
    p = patch('test_code.f') 
    m = p.start() 
    m.return_value = 'patched' 
    return m 

test_code.py

def f(): 
    return 'unpatched' 

import patch_stuff 

if __name__ == "__main__": 
    m = patch_stuff.patch_it_up() 
    print m() 

Это напечатает ожидаемый 'patched' строку.


Это делает этот сценарий не очень практично, но все примеры в документации показывает только возможность модификации модулей импортированных в текущем контексте. Например, это также будет работать:

from mock import patch 

def patch_it_up(): 
    import test_code 
    p = patch('test_code.f') 
    m = p.start() 
    m.return_value = 'patched' 
    print "inside patch_it_up:", test_code.f() 
Смежные вопросы