如何使用IContextAwareDefaultFactory测试内容类型

时间:2016-03-04 14:57:52

标签: testing plone zope dexterity acquisition

我们有一个基于敏捷的内容类型,必须从其父级继承字段的默认值。我们使用以下内容:

在模型中:

<model xmlns="http://namespaces.plone.org/supermodel/schema"
       xmlns:indexer="http://namespaces.plone.org/supermodel/indexer"
       xmlns:form="http://namespaces.plone.org/supermodel/form">
  <schema>
    ...
    <field name="subjects" type="zope.schema.Tuple" indexer:searchable="true">
      ...
      <defaultFactory>my.package.content.default_subjects</defaultFactory>
      ...
    </field>
  </schema>
</model>

工厂宣布如下:

from zope.schema.interfaces import IContextAwareDefaultFactory
...
@provider(IContextAwareDefaultFactory)
def default_subjects(context):
    return getattr(context, 'subjects', ())

这在运行实例时工作正常:

(Pdb) context
<MyType at /Plone/folder>
(Pdb) type(context)
<type 'Acquisition.ImplicitAcquisitionWrapper'>

但是因为上下文没有被包装而运行测试时失败了:

(Pdb) context
<MyType at test>
(Pdb) type(context)
<class 'my.package.content.MyType'>

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

你正在做的一切正确。 在代码中,您尝试访问这样的主题:

>>> object.subjects

从未设置subjects时,Dexterity的__getattr__实现开始工作。缺少属性的__getattr__魔法由Python实现。它以某种方式失去了采集包装器。 在取消采集包装后,aq_parent和都不会继续工作。 在我的测试中,我能够通过调用

来规避这个问题
>>> object.__getattr__('subjects')

但这并不令人满意。

在视图代码中,您没有此问题,因为视图根本不会通过object.subjects访问该属性,因此获取上下文永远不会丢失。

我在这里完成了我的分析,但是我在plone.dexterity的bug报告中注意到了我的发现。也许你想在那里提供一个最小的测试: https://github.com/plone/plone.dexterity/issues/53