对于项目,我有一个包含许多子组件的复杂主对象。这些对象的设置由Constructor接口控制,我将其绑定到各种生命周期&工作流事件,如下:
@grok.subscribe(schema.ICustomFolder, lifecycleevent.IObjectAddedEvent)
def setup_custom_folder(folder, event):
interfaces.IConstructor(folder).setup()
@grok.subscribe(schema.ICustomFolder, lifecycleevent.IObjectModifiedEvent)
def setup_custom_folder(folder, event):
interfaces.IConstructor(folder).update()
我希望能够做的是在没有依赖于事件处理程序的的情况下测试构造函数方法。我已经尝试通过直接创建对象来避免生命周期事件:
def test_custom_item_constructor(self):
master = createContent('model.master_object',
needed_attribute = 2
)
folder = createContent('model.custom_folder',
__parent__ = master
)
self.assertEqual(0, len(folder))
constructor = interfaces.IConstructor(folder)
constructor.setup()
self.assertEqual(2, len(folder))
setup
方法在Custom_Folder
实例中创建了许多项,具体取决于主对象上提供的属性。但是,这是挂起的,我认为是由于这两个对象实际上都不属于该网站,因此没有获取权限。我可以通过将主对象上的createContent
更改为createContentInContainer
并将其添加到测试站点的相应部分来实现此目的,但这会触发生命周期事件的所有,最终做了构造函数调用,这不允许我单独测试它们。
我已经尝试过使用模拟对象,但是在构造函数.setup
期间发生的内容创建变得很混乱。
最好的方法是什么?
答案 0 :(得分:2)
我不确定这是否是最好的方法,但我设法通过首先禁用相关的事件处理程序,然后在网站中正确创建内容来获得我想要的结果:
def test_custom_item_constructor(self):
zope.component.getGlobalSiteManager().unregisterHandler(
adapters.master.constructor.setup_masterobject,
required=[schema.IMasterObject, lifecycleevent.IObjectAddedEvent]
)
zope.component.getGlobalSiteManager().unregisterHandler(
adapters.custom.constructor.setup_customfolder,
required=[schema.ICustomFolder, lifecycleevent.IObjectAddedEvent]
)
master = createContentInContainer(self.portal, 'model.master_object',
needed_attribute = 2
)
folder = createContentInContainer(master, 'model.custom_folder',
__parent__ = master
)
self.assertEqual(0, len(folder))
constructor = interfaces.IConstructor(folder)
constructor.setup()
self.assertEqual(2, len(folder))
这足以解除由添加新主对象触发的事件链。