0

I have a custom model in django with overriden to_python() and get_db_prep_save() methods. I discovered a bug: when dumping and reloading data it was inconsistent. The bug is fixed but I want to unittest it with simple json string.

My question is: how can I call loaddata / dumpdata inside unittest.

I want to to create following scenarios:

from django.test import TestCase
class CustomModelTest(TestCase):
    def test_load_fixture(self):
        mydata = '[{"model": "some_app.custommodel", "pk": 1, "fields": {"custom_field": "some correct value"}}]'
        django.some_interface_to_load_fixture.loaddata(mydata) // data could be as json string, file, stream
        make some assertions on database model custommodel

    def test_dump_fixture(self):
        mymodel = create model object with some data
        result = django.some_interface_to_dump_fixture.dumpdata()
        make some assertions on result

I know there is fixture=[] field which can be used in django unittests, it could solve loading fixtures scenarios. But if someone could point me to some interface to load or dump fixture data on demand it would be great.

makozaki
  • 3,772
  • 4
  • 23
  • 47
  • can you post your methods for dumping and reloading? and also why dont you simply use `json` module for this? – Yugandhar Chaudhari Sep 26 '19 at 07:12
  • I'm asking if there are some methods already in djago to do it. The code is just a concept. I can adjust the data according to existing interface if there is one. I'm assuming there is. If I can load data with `python manage.py loaddata data.json` there should albo be some interface that can be used directly in django module in unittests. – makozaki Sep 26 '19 at 07:16
  • 1
    Django does that using this `from django.core.serializers.json import Serializer,Deserializer` – Yugandhar Chaudhari Sep 26 '19 at 07:31
  • How about using the management command `loaddata`? You can also just call it in code. – dirkgroten Sep 26 '19 at 10:42
  • You can instantiate the `Command` and then run `execute` with the arguments that the management command would take. Look at the source code to see which arguments is will require (you have to pass the defaults if you're not calling from the command line) – dirkgroten Sep 26 '19 at 10:46
  • @YugandharChaudhari That's what I was looking for. Many thanks! Your comment led me to proper django docs [Serializing Django objects](https://docs.djangoproject.com/en/2.2/topics/serialization/) – makozaki Sep 26 '19 at 11:21

1 Answers1

1

Thanks to @YugandharChaudhari comment I came up with solution using django.core.serializers:

import json
from django.core import serializers
from django.test import TestCase
from some_app.models import CustomModel

class CustomModelTest(TestCase):
    def test_deserializing(self):
        test_data = [
            {"model": "some_app.custommodel",
             "pk": 1,
             "fields":
                 {
                     "custom_field": "some correct value"}
             }
        ]
        result = list(serializers.deserialize('json', json.dumps(test_data)))
        self.assertEqual(result[0].object.custom_field, 'some data after deserialization')

    def test_serializing(self):
        custom_model_obj = CustomModel(id=1, custom_field='some data')
        result_json = json.loads(serializers.serialize('json', [custom_model_obj]))
        self.assertEqual('some data after serialization', result_json[0]['fields']['custom_field'])
makozaki
  • 3,772
  • 4
  • 23
  • 47