【问题标题】:How do you use factory_boy to model a MongoEngine EmbeddedDocument?如何使用 factory_boy 为 MongoEngine EmbeddedDocument 建模?
【发布时间】:2013-01-15 20:22:31
【问题描述】:

我正在尝试使用 factory_boy 来帮助为我的测试生成一些 MongoEngine 文档。我无法定义 EmbeddedDocumentField 对象。

这是我的 MongoEngine Document:

class Comment(EmbeddedDocument):
    content = StringField()
    name = StringField(max_length=120)

class Post(Document):
    title = StringField(required=True)
    tags = ListField(StringField(), required=True)
    comments = ListField(EmbeddedDocumentField(Comment))

这是我部分完成的 factory_boy Factory

class CommentFactory(factory.Factory):
    FACTORY_FOR = Comment
    content = "Platinum coins worth a trillion dollars are great"
    name = "John Doe"

class BlogFactory(factory.Factory):
    FACTORY_FOR = Blog
    title = "On Using MongoEngine with factory_boy"
    tags = ['python', 'mongoengine', 'factory-boy', 'django']
    comments = [factory.SubFactory(CommentFactory)] # this doesn't work

知道如何指定comments 字段吗?问题是工厂男孩试图创建Comment EmbeddedDocument。

【问题讨论】:

    标签: python django mongoengine factory-boy


    【解决方案1】:

    我不确定这是否是您想要的,但我刚开始研究这个问题,这似乎有效:

    from mongoengine import EmbeddedDocument, Document, StringField, ListField, EmbeddedDocumentField
    import factory
    
    class Comment(EmbeddedDocument):
        content = StringField()
        name = StringField(max_length=120)
    
    class Post(Document):
        title = StringField(required=True)
        tags = ListField(StringField(), required=True)
        comments = ListField(EmbeddedDocumentField(Comment))
    
    
    class CommentFactory(factory.Factory):
        FACTORY_FOR = Comment
        content = "Platinum coins worth a trillion dollars are great"
        name = "John Doe"
    
    class PostFactory(factory.Factory):
        FACTORY_FOR = Post
        title = "On Using MongoEngine with factory_boy"
        tags = ['python', 'mongoengine', 'factory-boy', 'django']
        comments = factory.LazyAttribute(lambda a: [CommentFactory()])
    
    >>> b = PostFactory()
    >>> b.comments[0].content
    'Platinum coins worth a trillion dollars are great'
    

    如果我错过了什么,我不会感到惊讶。

    【讨论】:

    • 当我们初始化主工厂时,您需要包含 EmbeddedDocumentFactory,因为第一个人已经包含为嵌入式文档工厂创建工厂。
    【解决方案2】:

    我现在这样做的方式是阻止基于 EmbeddedDocuments 的工厂构建。所以,我设置了一个 EmbeddedDocumentFactory,如下所示:

    class EmbeddedDocumentFactory(factory.Factory):
    
        ABSTRACT_FACTORY = True
    
        @classmethod
        def _prepare(cls, create, **kwargs):                                        
            return super(EmbeddedDocumentFactory, cls)._prepare(False, **kwargs)
    

    然后我继承它来为 EmbeddedDocuments 创建工厂:

    class CommentFactory(EmbeddedDocumentFactory):
    
        FACTORY_FOR = Comment
    
        content = "Platinum coins worth a trillion dollars are great"
        name = "John Doe"
    

    这可能不是最好的解决方案,所以我会等其他人回复后再接受这个答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多