2012-08-09 65 views
1

对于一个项目,我有一个复杂的主对象,其中包含一些子组件。设置这些对象是通过构造函数接口控制,我绑定到不同的生命周期&工作流事件,像这样的了:测试敏捷内容创建隔离

@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实例内的物品,依赖于主对象所提供的属性。然而,这是悬而未决,我认为这是由于对象实际上不属于该网站,所以没有获得许可。我可以通过改变主对象的createContentcreateContentInContainer并将其添加到测试现场的适当部分得到这个,但触发生命周期事件,其最终做的构造函数调用的所有,这并不让我单独测试它们。

我已经尝试过使用模拟对象来实现这个功能,但是那些处理内容创建的内容创建应该是在构造函数.setup中发生的。

解决此问题的最佳方法是什么?

回答

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)) 

这足以解除由添加新主对象触发的事件链。