Как получить область видимости для каждого тестового случая для объектов, внедренных зависимостями в Python?
Я использую Python-Inject, Python 2.6 (с unittest2).
У нас есть классы для тестирования, которые используют инъекцию, и тестовые случаи, которые также используют те же значения. В настоящее время мы используем inject.appscope, чтобы "синглетонизировать" значения. В противном случае они создаются для каждого пользователя.
import inject
class A(object):
'''shared data between many parts'''
...
class Foo(object):
'''uses a to do stuff'''
a = inject.attr('a', A)
def bar(self):
self.a.doStuff()
class TestFoo(TestCase):
a = inject.attr('a', A)
def setUp(self):
self.foo = Foo()
def testBar(self):
self.foo.bar()
self.assertTrue(self.a.stuffWasDone())
self.assertFalse(self.a.stuffWasDoneTwice())
def testBarTwice(self):
self.foo.bar()
self.foo.bar()
self.assertTrue(self.a.stuffWasDoneTwice())
injector = inject.Injector()
injector.bind(A, scope=inject.appscope)
inject.register(injector)
runTests()
В идеале, я хотел бы сбрасывать A после каждого теста, чтобы избежать перекрестного загрязнения. (В настоящее время сделать что-то вроде A.reset() в tearDown()..)
inject.reqscope
поддерживает что-то вроде этого (локальный набор экземпляров), но я не знаю, куда звонить register()
& unregister()
(который сбрасывает кеш объекта инъекций). От слишком поздно setUp()
а также tearDown()
, поскольку Foo.a уже может быть вызван в Foo.__init__()
для каждого из них.
Любые идеи о том, как это сделать, или я должен использовать другой подход?
1 ответ
Ты можешь использовать setUp
а также tearDown
зарегистрировать / отменить регистрацию области, рассматривая каждый вызов метода тестирования как новый "запрос".
Со следующими изменениями ваши тестовые модули проходят:
class TestFoo(unittest2.TestCase):
a = inject.attr('a', A)
def __init__(self, *n, **kw):
unittest2.TestCase.__init__(self, *n, **kw)
self.unit_scope = inject.reqscope
def setUp(self):
self.foo = Foo()
self.unit_scope.register()
def tearDown(self):
self.unit_scope.unregister()
...
И свяжи свой A
пример использования inject.reqscope
:
injector = inject.Injector()
injector.bind(A, scope=inject.reqscope)