Как исправить внутренние функции модуля с помощью mock?

По "внутренней функции", Я имею в виду функцию, которая вызывается из того же модуля, в котором она определена.

Я использую фиктивную библиотеку , в частности декораторы патча , в своих модульных тестах. Это модульные тесты Django, но это должно применяться к любым тестам Python.

У меня есть один модуль с несколькими функциями, многие из которых вызывают друг друга. Например (фиктивный код, игнорируйте отсутствие decimal.Decimal):

TAX_LOCATION = 'StateName, United States'

def add_tax(price, user):
    tax = 0
    if TAX_LOCATION == 'StateName, UnitedStates':
        tax = price * .75
    return (tax, price+tax)

def build_cart(...):
    # build a cart object for `user`
    tax, price = add_tax(cart.total, cart.user)
    return cart

Они являются частью более глубокой цепочки вызовов (func1 -> func2 -> build_cart -> add_tax), все они находятся в одном модуле.

] В своих модульных тестах я хотел бы отключить налоги, чтобы получить стабильные результаты. Насколько я понимаю, у меня есть два варианта: 1) исправить TAX_LOCATION (скажем, пустой строкой), чтобы add_tax фактически ничего не делал, или 2) исправить add_tax, чтобы просто вернуть (0, цена).

Однако , когда я пытаюсь исправить любой из них, патч, похоже, работает извне (я могу импортировать исправленную часть внутри теста и распечатать ее, получив ожидаемые значения), но, похоже, не имеет внутреннего эффекта (результаты, которые я получаю из кода, ведут себя как если бы патч не применялся).

Мои тесты выглядят следующим образом (опять же, фиктивный код):

from mock import patch
from django.test import TestCase

class MyTests(TestCase):

    @patch('mymodule.TAX_LOCATION', '')
    def test_tax_location(self):
        import mymodule
        print mymodule.TAX_LOCATION # ''
        mymodule.func1()
        self.assertEqual(cart.total, original_price) # fails, tax applied

    @patch('mymodule.add_tax', lambda p, u: (0, p))
    def test_tax_location(self):
        import mymodule
        print mymodule.add_tax(50, None) # (0, 50)
        mymodule.func1()
        self.assertEqual(cart.total, original_price) # fails, tax applied

Кто-нибудь знает, возможно ли с помощью mock исправлять функции, используемые внутри, как это, или мне не повезло ?

23
задан eternicode 17 March 2011 в 15:21
поделиться