I'm trying to use factory_boy to help generate some MongoEngine documents for my tests. I'm having trouble defining EmbeddedDocumentField
objects.
Here's my 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))
Here's my partially completed 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
Any ideas how to specify the comments
field? The problem is that factory-boy attempts to create the Comment
EmbeddedDocument.
I'm not sure if this is what you want but I just started looking at this problem and this seems to work:
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'
I wouldn't be surprised if I'm missing something though.
The way that I'm doing it right now is to prevent the Factories based on EmbeddedDocuments from building. So, I've setup up an EmbeddedDocumentFactory, like so:
class EmbeddedDocumentFactory(factory.Factory):
ABSTRACT_FACTORY = True
@classmethod
def _prepare(cls, create, **kwargs):
return super(EmbeddedDocumentFactory, cls)._prepare(False, **kwargs)
Then I inherit from that to create factories for EmbeddedDocuments:
class CommentFactory(EmbeddedDocumentFactory):
FACTORY_FOR = Comment
content = "Platinum coins worth a trillion dollars are great"
name = "John Doe"
This may not be the best solution, so I'll wait on someone else to respond before accepting this as the answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With