2

コンテキスト: 現在のプロジェクトでは、plone.app.testing を使用してテスト環境をセットアップしようとしています。コードは github で入手できます: https://github.com/collective/collective.rcse

セットアップにいくつかのメンバーを追加しようとしていますが、次の例外が発生します:

Traceback (most recent call last):
  File "/Uses/toutpt/myproject/buildout-cache/eggs/zope.testing-3.9.7-py2.7.egg/zope/testing/testrunner/runner.py", line 366, in run_layer
    setup_layer(options, layer, setup_layers)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/zope.testing-3.9.7-py2.7.egg/zope/testing/testrunner/runner.py", line 628, in setup_layer
    setup_layer(options, base, setup_layers)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/zope.testing-3.9.7-py2.7.egg/zope/testing/testrunner/runner.py", line 633, in setup_layer
    layer.setUp()
  File "/Uses/toutpt/myproject/buildout-cache/eggs/plone.app.testing-4.2.2-py2.7.egg/plone/app/testing/helpers.py", line 343, in setUp
    self.setUpPloneSite(portal)
  File "/Uses/toutpt/myproject/src/collective.rcse/collective/rcse/testing.py", line 71, in setUpPloneSite
    self.create_user(portal, "simplemember1")
  File "/Uses/toutpt/myproject/src/collective.rcse/collective/rcse/testing.py", line 82, in create_user
    regtool.addMember(username, username)
  File "<string>", line 10, in addMember
  File "/Uses/toutpt/myproject/buildout-cache/eggs/plone.protect-2.0.2-py2.7.egg/plone/protect/utils.py", line 46, in _curried
    return callable(*args, **kw)
  File "<string>", line 10, in addMember
  File "/Uses/toutpt/myproject/buildout-cache/eggs/AccessControl-3.0.8-py2.7-macosx-10.6-x86_64.egg/AccessControl/requestmethod.py", line 70, in _curried
    return callable(*args, **kw)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/Products.CMFCore-2.2.7-py2.7.egg/Products/CMFCore/RegistrationTool.py", line 160, in addMember
    membership.addMember(id, password, roles, domains, properties)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/Products.PlonePAS-4.1.1-py2.7.egg/Products/PlonePAS/tools/membership.py", line 136, in addMember
    acl_users._doAddUser(id, password, roles, domains)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/Products.PlonePAS-4.1.1-py2.7.egg/Products/PlonePAS/pas.py", line 42, in _doAddUser
    retval = _old_doAddUser(self, login, password, roles, domains)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/Products.PluggableAuthService-1.10.0-py2.7.egg/Products/PluggableAuthService/PluggableAuthService.py", line 1004, in _doAddUser
    if useradder.doAddUser( login, password ):
  File "/Uses/toutpt/myproject/buildout-cache/eggs/Products.membrane-2.1.9-py2.7.egg/Products/membrane/plugins/usermanager.py", line 283, in doAddUser
    adder = getCurrentUserAdder(self)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/Products.membrane-2.1.9-py2.7.egg/Products/membrane/utils.py", line 46, in getCurrentUserAdder
    name, adder = adders.next()
  File "/Uses/toutpt/myproject/buildout-cache/eggs/zope.component-3.9.5-py2.7.egg/zope/component/registry.py", line 172, in getUtilitiesFor
    for name, utility in self.utilities.lookupAll((), interface):
  File "/Uses/toutpt/myproject/buildout-cache/eggs/five.localsitemanager-2.0.5-py2.7.egg/five/localsitemanager/registry.py", line 77, in _uncached_lookupAll
    tmp_result[k] = _wrap(v, registry)
  File "/Uses/toutpt/myproject/buildout-cache/eggs/five.localsitemanager-2.0.5-py2.7.egg/five/localsitemanager/registry.py", line 143, in _wrap
    registry_site = registry_site.__parent__
AttributeError: 'BaseGlobalComponents' object has no attribute '__parent__'

このトレース ショー メンブレンはメンバーを追加するために呼び出されますが、IUserAdder コンポーネントを見つけようとすると、コンポーネント レジストリは次のコードで例外を発生させます。

def _wrap(comp, registry):
    """Return an aq wrapped component with the site as the parent but
    only if the comp has an aq wrapper to begin with.
    """

    # If component is stored as a ComponentPathWrapper, we traverse to
    # the component using the stored path:
    if isinstance(comp, ComponentPathWrapper):
        comp = getSite().unrestrictedTraverse(comp.path)
        if IAcquirer.providedBy(comp):
            return _rewrap(comp)
        else:
            return comp

    # BBB: The primary reason for doing this sort of wrapping of
    # returned utilities is to support CMF tool-like functionality where
    # a tool expects its aq_parent to be the portal object. New code
    # (ie new utilities) should not rely on this predictability to
    # get the portal object and should search out an alternate means
    # (possibly retrieve the ISiteRoot utility). Although in most
    # cases getting at the portal object shouldn't be the required pattern
    # but instead looking up required functionality via other (possibly
    # local) components.

    if registry.__bases__ and IAcquirer.providedBy(comp):
        current_site = getSite()
        registry_site = Acquisition.aq_base(registry.__parent__)
        if not ISite.providedBy(registry_site):
            registry_site = registry_site.__parent__

        ...

また、テスト中、 registry_site にはparentがありません。PDBを使用して試したことは次のとおりです。

(Pdb) registry_site
<BaseGlobalComponents test-stack-3>
(Pdb) ISite.providedBy(registry_site)
False
(Pdb) registry
<zope.component.globalregistry.GlobalAdapterRegistry object at 0x105499990>
(Pdb) getSite()
<PloneSite at /plone>
(Pdb) Acquisition.aq_base(registry.__parent__)
<BaseGlobalComponents test-stack-3>
(Pdb) registry.__bases__
(<zope.component.globalregistry.GlobalAdapterRegistry object at 0x1049238d0>,)
(Pdb) registry
<zope.component.globalregistry.GlobalAdapterRegistry object at 0x105499990>

テスト中にのみ発生するため、テストのセットアップに何かを追加する必要があります。

4

2 に答える 2

3

これは、設定した方法とほぼ同じです。

def setUpZope(self, app, configurationContext):
    import collective.indexing
    import Products.membrane

    self.loadZCML(package=collective.indexing)
    self.loadZCML(package=Products.membrane)

    z2.installProduct(app, 'collective.indexing')
    z2.installProduct(app, 'Products.membrane')

    # + your dexterity.membrane product setup

def setUpPloneSite(self, portal):
    from zope.publisher.browser import TestRequest
    from zope.globalrequest import setRequest
    request = TestRequest()
    setRequest(request)

    # + your dexterity.membrane product policy
    # + create (and reindex) content (with dexterity.membrane)

    import transaction
    transaction commit()

それでも、他のすべてが失敗し、機能テストを行おうとしていて<includeDependencies />、パッケージで -directive を使用している場合は、次のようにして、フィクスチャの z3c.autoinclude を再度有効にすることができますsetUpZope

    # Enable z3c.autoinclude
    configurationContext._features = set([
        feature for feature in configurationContext._features
        if feature != "disable-autoinclude"
    ])
于 2013-10-08T13:40:53.073 に答える
2

解決策を見つけました。

使用するカスタム ユーザー adder は、永続化されていない SimpleItem でした。Five.localsitemanager は、実際には取得できないものの親を取得しようとしていました。それをオブジェクトに変更するとうまくいきました。

参照: https://github.com/collective/collective.rcse/commit/f05d9e92bf4578ca82099eec714743903d181173

ただし、テスト以外で機能する理由の手がかりはありません。

于 2013-10-08T15:09:07.287 に答える