Wednesday, July 24, 2019

Re: Mocking models or at least creating Fakes.

On Wed, 2019-07-24 at 12:05 +0100, Roger Gammans wrote:
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?

I've done some more research and found at least the origins of the problem is that the ORM persists Foriegn objects (since 1.8). ( Which I'm sure sure removes a whole pile of nasty corner cases form the ORM).

Anyway for me the following is an alternative pattern which works; requiring only changes to the TestCase; ( because the FK is a property you
have to patch the class otherwise setattr is called with the Fake, the same is in the original code).


class TestThing(TestCase):
    def test_x():
        fake = FakeThingy()
        def getter(om):
            return fake

        thingy_getter = property(getter)
        out = m.Foo( title ="")
        with unittest.mock.patch.object(out.__class__,'thing',thingy_getter):
            self.assertEqual(out.title,"")



I'm still interested in other possible solutions out there .

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

No comments:

Post a Comment