Mam tę funkcję, którą chcę przetestować:

def get_django_model(django_model):
    try:
        app_config = apps.get_app_config("myapp")
        model = app_config.get_model(django_model)
        return model
    except Exception:
        raise DjangoModelMissing(f"Missing django model: {django_model}")

A oto mój test:

class ModelInstanceTest(TestCase):
    def test_get_django_model(self):
        model_class = get_djagno_model("Foo")
        self.assertIsInstance(model_class, models.Foo) 

Powyższy test kończy się niepowodzeniem, mówiąc AssertionError: <class 'models.Foo'> is not an instance of <class 'models.Foo'>.

Jeśli jednak zamienię assertIsInstance na assertIs, test zakończy się pomyślnie.

Czy ktoś może wyjaśnić, co się dzieje?

Ten post jest powiązany, ale tak naprawdę nie wyjaśnia różnych wyników: Test Pythona do sprawdź typ instancji.

1
dwvldg 19 grudzień 2019, 16:01
2
Klasa rzeczywiście nie jest instancją tej klasy.
 – 
Willem Van Onsem
19 grudzień 2019, 16:02
1
Masz również literówkę w swoim teście get_djagno_model (django)
 – 
Sayse
19 grudzień 2019, 16:03

1 odpowiedź

Twoja funkcja get_django_model zwraca odniesienie do klasy , a nie obiekt (instancję) tej klasy. Więc nie zwraca Foo obiektu , zwraca odniesienie do klasy Foo.

Dlatego model_class jest rzeczywiście równe models.Foo, ale nie wystąpieniu models.Foo. Jest to jednak instancja type, więc możesz sprawdzić, czy:

class ModelInstanceTest(TestCase):

    def test_get_django_model(self):
        model_class = get_djagno_model('Foo')
        self.assertIsInstance(model_class, type)
        self.assertEqual(model_class, models.Foo)
2
Willem Van Onsem 19 grudzień 2019, 16:04
Kiedy mówisz, że zwraca odwołanie do klasy, czy to to samo, co mówisz, że zwraca metaklasę?
 – 
dwvldg
19 grudzień 2019, 16:08
@dwvldg: cóż, typ klasy to meta-klasa. Więc tak, możesz powiedzieć, że model_class jest obiektem metaklasy.
 – 
Willem Van Onsem
19 grudzień 2019, 16:08
Czy więc type i meta-class to to samo? Innymi słowy, czy self.assertIsInstance(model_class, type) mówi tylko, że model_class jest instancją metaklasy? Czy istnieje inny sposób sprawdzenia, czy coś jest instancją metaklasy?
 – 
dwvldg
19 grudzień 2019, 16:13
@dwvldg: ale nie ma wyraźnego rozróżnienia, ponieważ w Pythonie wszystko jest obiektem. Typ type to type itd., więc można powiedzieć, że „metahierarchia” trwa aż do nieskończoności.
 – 
Willem Van Onsem
19 grudzień 2019, 16:14