2012-10-20 36 views
1

我的观点如下:测试用例的金字塔

@view_config(name="clone-site", context=ctx.Site) 
def clone_site(context, request): 
"""Cloning the current Site. 
""" 

doc = context.__parent__.get_conn(app=context.appname).SiteDocument.one({'title':context.slug}) 
doc1 = context.__parent__.get_conn(app=context.appname).SiteDocument() 
doc1['title'] = doc['title']+ '1' 
doc1['slug'] = str(doc['slug'] + '1') 
doc1.save() 
for post in context.pages_data().find({'parent':context.__name__}): 
    page = ctx.Page(parent=context) 
    page1 = page.pages_data().PageDocument() 
    page1['parent'] = page.__parent__.__name__=str(doc1['title']) 
    page1['title'] = page.title=post['title'] 
    page1['slug'] = page.__name__=page.slug=str(post['slug']) 
    page1['source'] = page.source= str(post['source']) 
    page1['data'] = post['data'] 
    page1.save() 

return HTTPFound(location=request.resource_url(context)) 

我写了一个测试用例上述观点:

def test_clone_site(self): 
    from piano.views.sites import clone_site 
    from piano.resources import contexts as ctx 
    from piano.lib import base as b 
    request = testing.DummyRequest(path='/sample/dhara') 
    context = testing.DummyResource()   
    response = clone_site(context, request) 
    self.assertEqual(response.location, 'http://localhost:8080/sample/dhara') 

MY资源树如下:

class Root(b.ContextBase): 
"""The root segment is the entry-point into the context tree. From the 
root it will try to find an application, then the site, then any pages. The 
only exception are services (/services) which can only be accessed from the 
the root. 
""" 
__acl__ = [ (Allow, Everyone, 'view'), 
      (Allow, 'group:editors', 'edit') ] 

def __init__(self, request): 
    self.request = request 

def __getitem__(self, key): 
    # If /services return the service context 
    if key == c.SRVC_NAME: 
     return Service(key=key, parent=self) 
    #Try and return an app context otherwise 
    try: 
     return self.app(key=key, parent=self) 
    except: 
     raise KeyError(key) 

class Service(b.ContextBase): 

pass 
@implementer(i.IApp) 
class App(b.ContextBase): 

def __getitem__(self, key): 
    try: 
     return Site.find(key=key, parent=self) 
    except: 
     raise KeyError(key) 

def get_sites(self): 
    """Returns a list of sites under the application. 
    """ 
    #@cache_region('hourly', 'site.list') 
    def _find_sites(a): 
     docs = self.get_conn(a).SiteDocument.find({}, {'title':1, 'slug':1}) 
     return list(SiteItem(s['title'], '/'.join([a, s['slug']])) for s in docs) 
    #Get the list of available sites 
    site_list = _find_sites(self.appname) 
    return site_list 

class Version(b.ContextBase): 

def __getitem__(self, key): 
    try: 
     return self.finder(key, self.__parent__, versioned=True) 
    except: 
     raise KeyError(key) 

def compare(self, source, target): 
    """Compares two versions and returns the changes. 
    """ 
    doc_source = self.finder(source, self.__parent__, versioned=True) 
    doc_target = self.finder(target, self.__parent__, versioned=True) 
    return diff(
     doc_source.data, 
     doc_target.data) 

def rollback(self, source, target): 
    pass 

class Page(b.ContextBase): 

def __getitem__(self, key): 
    try: 
     if key == c.V: 
      #Return a versioned instance of the page. It finds the 
      #artifact by assigning its 'finder' function to the context. 
      return Version(key=key, parent=self, finder=self.find) 
     #Return the head page 
     return Page.find(key=key, parent=self) 
    except: 
     raise KeyError(key) 

@classmethod 
def find(cls, key, parent, versioned=False): 
    """Finds a page by its parent and slug or version. 
    """ 
    #@cache_region('hourly', 'page.find') 
    def _find_page(k, p, s, a, v): 
     if v: 
      return parent.history_data().one({'pageid': parent.id, 'version':int(k)}) 
     return parent.pages_data().one({'parent': p, 'slug':k}) 
    #Find the page 
    doc = _find_page(key, 
        parent.__name__, 
        parent.sitename, 
        parent.appname, 
        versioned) 
    return cls(
     key=key, 
     parent=parent, 
     id=doc['_id'], 
     title=doc['title'], 
     data=doc['data'], 
     slug=doc['slug'], 
     origin=doc['parent'], 
     views=doc['views'], 
     source=str(doc['source']), 
     date_created=doc['created']) 

def get_history(self): 
    """Finds the history for the page. 
    """ 
    docs = self.history_data().find({'pageid': self.id}) 
    return list((v['version'], v['archived']) for v in docs) 

def create(self, data): 
    """Creates a new page and associates it to a parent. 
    """ 
    doc = self.pages_data().PageDocument() 
    doc['title'] = self.title = data['page']['title'] 
    doc['slug'] = self.slug = self.__name__ = str(h.urlify(self.title)) 
    doc['source'] = self.source = str(data['page']['source']) 
    doc['parent'] = str(self.__parent__.__name__) 
    #Try to import custom models and get doc 
    try: 
     #Explicitly look for a 'models' module with a 'PageModel' class 
     mod = __import__('.'.join([self.source, c.MODEL_PATH]), fromlist=[self.source]) 
     pdoc = getattr(mod, c.MODEL_NAME) 
    except ImportError: 
     logger.warn("Cannot import '%s.models' module" % self.source) 
    except AttributeError: 
     logger.warn("Cannot load '%s.models.PageModel' class" % self.source) 
    else: 
     #Embed a new document 
     doc['data'] = pdoc() 
    doc.save() 
    return self 

def update(self, data, archive=True): 
    """Update myself with data (and copy to the archives collection) 
    """ 
    doc = self.pages_data().PageDocument.get_from_id(self.id) 
    doc['title'] = self.title = data['page']['title'] 
    doc['slug'] = self.slug = self.__name__ = str(h.urlify(data['page']['slug'])) 
    doc['data'] = self.data = data['data'] 
    doc['version'] = doc['version'] + 1 
    doc.save(validate=False) 
    #Create archived version? 
    if archive: 
     ver = deepcopy(doc) 
     ver['pageid'] = doc['_id'] 
     ver['archived'] = h.now() 
     del(ver['_id']) 
     self.history_data().insert(ver, validate=False) 
    return self 

@implementer(i.ISite) 
class Site(Page): 

def __getitem__(self, key): 
    try: 
     return Page.find(key, self) 
    except: 
     raise KeyError(key) 

@classmethod 
def find(cls, key, parent): 
    """Returns a single site by its slug. 
    """ 
    @cache_region('hourly', 'site.find') 
    def _find_site(k, a): 
     return parent.get_conn(app=a).SiteDocument.one({'slug':k}) 
    #Find the site 
    doc = _find_site(key, parent.__name__) 
    return cls(
     key=key, 
     parent=parent, 
     id=doc['_id'], 
     title=doc['title'], 
     slug=doc['slug'], 
     views=doc['views'], 
     date_created=doc['created']) 

def save(self, data, include_default=False): 
    """Saves the primary site details and creates a new collection to house 
    the pages in. It also creates a default (Home) page if needed. 
    """ 
    doc = self.get_conn(app=self.appname).SiteDocument() 
    doc['title'] = self.title = data['site']['title'] 
    doc['slug'] = self.slug = self.__name__ = str(h.urlify(self.title)) 
    doc.save() 
    #Create default (home) page? 
    if include_default: 
     page = Page(parent=self) 
     page.create(dict(page=dict(title=u'Home', source='sample.home'))) 
    return self 

def delete(self): 
    """Deletes the site and its associated collection. 
    """ 
    db = self.get_conn(app=self.appname) 
    db.SiteDocument.get_from_id(self.id).delete() 
    db.drop_collection(self.__name__) 

它产生以下错误:

ERROR: test_clone_site (piano.tests.MapperTests)  
Traceback (most recent call last): 
File "D:\Auto\kjq-piano-6830d29\src\piano\tests\__init__.py", line 70, in test_clone_site 
response = clone_site(context, request) 
File "D:\Auto\kjq-piano-6830d29\src\piano\views\sites.py", line 62, in clone_site 
doc=context.__parent__.get_conn(app=context.appname).SiteDocument.one({'title':context.slug}) 
AttributeError: 'NoneType' object has no attribute 'get_conn' 

我想检查URL返回对于正确的上下文是否正确。我无法设置正确的上下文。如何在测试用例的clone_site(context,request)调用中设置正确的上下文?

+0

尝试注释装饰器,我认为它正在修改一些参数 –

回答

0

那么现在你的测试用例使用testing.DummyResource()作为上下文,它有__parent__ = None,这就是为什么你会看到你所看到的错误。

要解决这个问题,您需要使上下文看起来像您的视图所期待的。您可以通过附加属性(您有效地嘲讽了上下文)做到这一点:

parent = testing.DummyResource() 
parent.get_conn = # some function to get a connection 
context.__parent__ = parent 
context.app_name = 'some app name' 

也可以加载实物,通过在真实的语境。