Wednesday, July 24, 2019

Mocking models or at least creating Fakes.

Hi,

The django ORM is being far to helpful for me in this case; I need to find some method of bypasssing it; for my unittests.

I've got system which look something like:-

## In models.py
class Thingy(models.Model):
    friendly_name = models.CharField(max_length =200)
    title = models.CharField(max_length =200)
    other_name = models.CharField(max_length =200)

    def get_client(self,):
        return None

# In tests.py with appropriate imports.
X = object()

class FakeThingy(Thingy):
    class Meta:
        proxy = True

    def __init__(self,):
        self.fake_proxy  = unittest.mock.sentinel

    def get_client(self):
        global x
        return X

class Foo(models.Model):
    title = models.CharField(max_length = 200, )
    thing = models.ForeignKey(Thingy, on_delete= models.PROTECT)
    def __str__(self,):
        return self.title


class TestThing(TestCase):
    def test_x():
        fake = FakeThingy()
        out = m.Foo( thing = fake )


All the error come from the last line when I try to construct a Foo.

Without FakeThinky deriving from Thingy I get a error that fake is not of the correct class,
and it is (as shown above) I get the following traceback.

File "tests.py"
        out = m.Foo( thing = fake )
  File ".../lib/python3.7/site-packages/django/db/models/base.py", line 483, in __init__
    _setattr(self, field.name, rel_obj)
  File ".../lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 216, in __set__
    instance._state.db = router.db_for_write(instance.__class__, instance=value)
  File ".../lib/python3.7/site-packages/django/db/utils.py", line 261, in _route_db
    if instance is not None and instance._state.db:
AttributeError: 'FakeBackend' object has no attribute '_state'


I'm sure someone here must have had to write unit test which deal with foreign jets before what approach did you end up taking?

-- 
Roger Gammans <rgammans@gammascience.co.uk>
Gamma Science

No comments:

Post a Comment