Django testing custom signal arguments with assertIsInstance: AssertionError: <class 'path.to.Foo'> is not an instance of <class 'path.to.Foo'>

Django testing custom signal arguments with assertIsInstance: AssertionError: <class 'path.to.Foo'> is not an instance of <class 'path.to.Foo'>

我正在使用 Django 3.2

我编写了一个引发自定义事件的应用程序,我正在为这些应用程序编写测试。

这是我的代码的相关部分:

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

当我运行测试时,我收到错误信息:

AssertionError: <class 'social.models.Foo'> is not an instance of <class 'social.models.Foo'>

这显然是一条无意义的错误消息,无法帮助我解决问题。

我的问题是为什么我无法使用 assertIsInstance 检查实例类型,以及如何检查信号接收器中的 class 类型?

信号中的sender通常是实例的class。因此,您写 self.assertIsInstance(self.sender, Foo) 等同于写 self.assertIsInstance(Foo, Foo) 这当然是不正确的,因为 Foo 不是 Foo 的实例(它可能是 [=17= 的实例]、typeModelBaseModel 的元class)。例如,请参阅以下代码段:

class Foo:
    pass

print(isinstance(Foo, Foo)) # False
print(isinstance(Foo, object)) # True
print(isinstance(Foo, type)) # True

相反,您想使用 assertIs 而不是 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