I am trying to write tests for my django models. However, I've got a problem with testing ManyToManyFields and haven't resolved it yet.
class TestVolunteeringModels(TestCase):
def setUp(self) -> None:
self.test_need = sample_need(title="Need", description="Description")
self.test_opportunity = sample_opportunity(title="Opportunity", description="Description")
for i in range(10):
self.test_category = sample_category(name="Category")
self.test_need.category = self.test_category
self.test_opportunity.category = self.test_category
def tearDown(self) -> None:
self.test_need.delete()
self.test_opportunity.delete()
Which brings me this error:
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use category.set() instead.
The problem is when I use .set() as written in traceback instructions, like this:
self.test_need.category.set(self.test_category)
self.test_opportunity.category.set(self.test_category)
It gives me another error, which says "TypeError: 'Category' object is not iterable"
So my question is how can I access ManyToMany field in this case, so I can test it freely?
CodePudding user response:
.set()
expects an iterable as argument, but the argument that you pass, self.test_category
, is not iterable.
You have two options:
- Use
.set([self.test_category,])
instead of.set(self.test_category)
. Thereby you are passing a list, which is iterable, instead of a single object, which is not iterable (therefor the error message that you get). - Alternatively, you could use
.add(self.test_category)
. The function.add()
takes individual objects as positional arguments, and adds them to any pre-existing catetories.
You should probably opt for .set()
though, because this ensures that after its execution, the set of associated categories will be precisely the one that you pass.