I am using Django 3.2
I have written an app that raises custom events, and I am writing tests for the apps.
Here is the relevant section of my code:
class TestAppModel(TestCase):
# .. set up instance variables etc.
def test_liked_signal_emits_correct_data(self):
self.signal_was_called = False
self.sender = None
self.instance = None
self.event_type = None
self.actor = None
def handler(sender, instance, event_type, actor, **kwargs):
self.signal_was_called = True
self.sender = sender
self.instance = instance
self.event_type = event_type
self.actor = actor
item_liked.connect(handler)
self.daddy.like(self.admin_user)
# Check that the sender is a Foo
self.assertIsInstance(self.sender, Foo) # <- Nonsensical error emitted here
When I run the test, I get the error message:
AssertionError: <class 'social.models.Foo'> is not an instance of <class 'social.models.Foo'>
Which obviously, is a nonsensical error message that doesn't help me solve the problem.
My question is why am I not able to check the instance type using assertIsInstance
, and how do I check the class type in the signal receiver?
The sender
in a signal is typically the class of the instance. Hence you writing self.assertIsInstance(self.sender, Foo)
is equivalent to writing self.assertIsInstance(Foo, Foo)
which of course is not correct as Foo
is not an instance of Foo
(It likely is an instance of object
, type
and ModelBase
(metaclass of Model
)). For instance see the following snippet:
class Foo:
pass
print(isinstance(Foo, Foo)) # False
print(isinstance(Foo, object)) # True
print(isinstance(Foo, type)) # True
Instead you want to use assertIs
instead of assertIsInstance
:
class TestAppModel(TestCase):
# .. set up instance variables etc.
def test_liked_signal_emits_correct_data(self):
self.signal_was_called = False
self.sender = None
self.instance = None
self.event_type = None
self.actor = None
def handler(sender, instance, event_type, actor, **kwargs):
self.signal_was_called = True
self.sender = sender
self.instance = instance
self.event_type = event_type
self.actor = actor
item_liked.connect(handler)
self.daddy.like(self.admin_user)
# Check that the sender is a Foo
self.assertIs(self.sender, Foo) # The sender should be Foo itself
self.assertIsInstance(self.instance, Foo) # The instance should be an instance of Foo