Testing python methods that call class methods
-
20-09-2019 - |
Question
I have a very simple method:
Class Team(models.Model):
def sides(self):
return SideNames.objects.filter(team=self)
SideNames is another model defined in the same file as Team,
Which when I try and test:
self.assertEquals(len(t.sides()), 2)
I get the following error:
return SideNames.objects.filter(team=self)
AttributeError: 'NoneType' object has no attribute 'objects'
but if I change the test to be
self.assertEquals(len(SideNames.objects.filter(team=t)), 2)
Then I don't get the error. What's the difference between calling SideNames.objects.filter from the test itself and calling the actual method?
For reference, here are the 2 classes in their entirety.
class Team(models.Model):
"""The model for a football team."""
class Admin:
pass
def __unicode__(self):
return u'%s' % self.name
def is_player(self, player):
"""Checks to see if 'player' is a member if this team. Returns True if they are, or False otherwise."""
try:
teamPlayer = TeamPlayers.objects.get(player=player, team=self)
return True
except ObjectDoesNotExist:
return False
def sides(self):
"""Return the side names for this team"""
return SideNames.objects.filter(team=self)
def updateSides(self, side_a, side_b):
"""Update the side names"""
names = SideNames.objects.filter(team=self);
a = SideNames.objects.get(name = names[0].name)
a.name = side_a
a.save()
b = SideNames.objects.get(name = names[1].name)
b.name = side_b
b.save()
name = models.CharField("Team Name", max_length=255)
organiser = models.ForeignKey(User)
class SideNames(models.Model):
"""Holds the names of the sides for each team"""
class Admin:
pass
def __unicode__(self):
"""Pretty print the SideNames object"""
return self.name
team = models.ForeignKey(Team)
name = models.CharField(max_length=128)
Solution
By any chance, does your test do something like this:
from myapp import models
...
models.SideNames = None
since that's the only explanation I can think of for why SideNames should be None in the context of that method.
As an aside, the method itself is pointless, as backwards relations are automatically provided by Django, so you could just call t.sidenames_set.all()
.
OTHER TIPS
In the module that defines the test, you're importing the name SideNames
from some other module. In the module where that sides
method is defined, the name SideNames
is not defined or imported.