1

我正在尝试使用 z3c.forms 开发一个新的小部件,并且我已经到了可以进行功能测试的地步。

不幸的是,当我使用表单设置测试时,当调用 updateWidgets 时会为 IWidgets 接口引发 ComponentLookupError,它应该只是从 z3c.form.field 中查找 FieldWidgets

我猜我没有在测试设置中正确注册 z3c.form,但我不知道如何修复它。

这是测试代码:

import unittest2 as unittest

import zope.interface
import zope.schema
from z3c.schema.optchoice import OptionalChoice

from zope.app.testing import setup as ztc_setup
from z3c.form.testing import TestRequest
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from zope.traversing.adapters import DefaultTraversable

from z3c.form import form, field
from widget import OptChoiceWidget, OptChoiceWidgetCustomTokenFactoryFactory

sample_terms = SimpleVocabulary([
                        SimpleTerm(value="first", title="First"),
                        SimpleTerm(value="second", title="Second")
                                ])

class ISchema(zope.interface.Interface):
    test_name = OptionalChoice(
            title= u"This is a title",
            values=sample_terms,
            value_type=zope.schema.TextLine(),
                          )
class SampleForm(form.BaseForm):
    widgets = [OptChoiceWidget]
    fields = field.Fields(ISchema)
    fields['test_name'].widgetFactory = OptChoiceWidgetCustomTokenFactoryFactory(('other', "Other"))
    ignoreContext = True

class TestFunctionalForm(unittest.TestCase):
    def setUp(self):
        #plone.z3cform/tests.py
        component.provideAdapter(DefaultTraversable, [None])
        self.context = ztc_setup.placefulSetUp(True)
    def tearDown(self):
        ztc_setup.placefulTearDown()
    def test_add_form(self):
        sample_form = SampleForm(self.context, TestRequest())
        data = sample_form.update()

错误信息:

ERROR: test_add_form (z3cwidgetoptchoice.tests.TestFunctionalForm)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/alex/git/z3c.widget.optchoice/z3cwidgetoptchoice/tests.py", line 174, in test_add_form
    data = sample_form.update()
  File "/home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/z3c.form-2.9.1-py2.6.egg/z3c/form/form.py", line 150, in update
    self.updateWidgets()
  File "/home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/z3c.form-2.9.1-py2.6.egg/z3c/form/form.py", line 127, in updateWidgets
    (self, self.request, self.getContent()), interfaces.IWidgets)
  File "/home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/zope.component-4.0.1-py2.6.egg/zope/component/_api.py", line 112, in getMultiAdapter
    raise ComponentLookupError(objects, interface, name)
ComponentLookupError: ((<z3cwidgetoptchoice.tests.SampleForm object at 0x462d990>, <z3c.form.testing.TestRequest instance URL=http://127.0.0.1>, <zope.site.folder.Folder object at 0x3f070c8>), <InterfaceClass z3c.form.interfaces.IWidgets>, u'')

这是我在堆栈跟踪中戳:

test_add_form (z3cwidgetoptchoice.tests.TestFunctionalForm) ... > /home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/zope.component-4.0.1-py2.6.egg/zope/component/_api.py(112)getMultiAdapter()
-> raise ComponentLookupError(objects, interface, name)
(Pdb) up
> /home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/z3c.form-2.9.1-py2.6.egg/z3c/form/form.py(127)updateWidgets()
-> (self, self.request, self.getContent()), interfaces.IWidgets)
(Pdb) self
<z3cwidgetoptchoice.tests.SampleForm object at 0x462d990>
(Pdb) self.request
<z3c.form.testing.TestRequest instance URL=http://127.0.0.1>
(Pdb) self.getContent()
<zope.site.folder.Folder object at 0x3f070c8>
(Pdb) list
122             return self.context
123
124         def updateWidgets(self, prefix=None):
125             '''See interfaces.IForm'''
126             self.widgets = zope.component.getMultiAdapter(
127  ->             (self, self.request, self.getContent()), interfaces.IWidgets)
128             if prefix is not None:
129                 self.widgets.prefix = prefix
130             self.widgets.mode = self.mode
131             self.widgets.ignoreContext = self.ignoreContext
132             self.widgets.ignoreRequest = self.ignoreRequest
(Pdb) c
ERROR

更新:

我还尝试在实例化 Sample 表单之前显式注册接口,但这并没有帮助,并且 ComponentLookupError 再次引发。

from z3c.form import form, field, interfaces
zope.interface.classImplementsOnly(field.FieldWidgets,
                                       interfaces.IWidgets)
4

0 回答 0