Package: django-mock-queries
Django Mock QueriesA library for mocking Django queryset functions in memory for testingFeaturesQuerySet style support for method chainingFiltering with Q objectsAggregates generationCRUD functionsField lookupsdjango-rest-framework serializer assertsExamplesfromdjango.db.modelsimportAvg,Qfromdjango_mock_queries.queryimportMockSet,MockModelqs=MockSet(MockModel(mock_name='john',email='john@gmail.com'),MockModel(mock_name='jeff',email='jeff@hotmail.com'),MockModel(mock_name='bill',email='bill@gmail.com'),)print([xforxinqs.all().filter(email__icontains='gmail.com').select_related('address')])# Outputs: [john, bill]qs=MockSet(MockModel(mock_name='model s',msrp=70000),MockModel(mock_name='model x',msrp=80000),MockModel(mock_name='model 3',msrp=35000),)print(qs.all().aggregate(Avg('msrp')))# Outputs: {'msrp__avg': 61666}qs=MockSet(MockModel(mock_name='model x',make='tesla',country='usa'),MockModel(mock_name='s-class',make='mercedes',country='germany'),MockModel(mock_name='s90',make='volvo',country='sweden'),)print([xforxinqs.all().filter(Q(make__iexact='tesla')|Q(country__iexact='germany'))])# Outputs: [model x, s-class]qs=MockSet(cls=MockModel)print(qs.create(mock_name='my_object',foo='1',bar='a'))# Outputs: my_objectprint([xforxinqs])# Outputs: [my_object]Test function that uses Django QuerySet:fromunittestimportTestCasefromunittest.mockimportpatchfromdjango_mock_queries.queryimportMockSet,MockModelclassTestApi(TestCase):"""Test function applies expected filters by patching Django's user model Manager or Queryset with a MockSet."""users=MockSet()user_objects=patch('django.contrib.auth.models.User.objects',users)defactive_users(self):"""Query active users."""returnUser.objects.filter(is_active=True).all()@user_objectsdeftest_api_active_users_filters_by_is_active_true(self):self.users.add(MockModel(mock_name='active user',is_active=True),MockModel(mock_name='inactive user',is_active=False))foruserinself.active_users():self.assertTrue(user.is_active)Test django-rest-framework model serializer:classCarSerializer(serializers.ModelSerializer):"""Car model serializer that includes a nested serializer and a method field."""make=ManufacturerSerializer()speed=serializers.SerializerMethodField()defget_speed(self,obj):returnobj.format_speed()classMeta:model=Carfields=('id','make','model','speed',)deftest_car_serializer_fields(self):"""Test serializer returns fields with expected values and mock the result of nested serializer for field `make`."""car=Car(id=1,make=Manufacturer(id=1,name='vw'),model='golf',speed=300)values={'id':car.id,'model':car.model,'speed':car.formatted_speed(),}assert_serializer(CarSerializer)\.instance(car)\.returns('id','make','model','speed')\.values(**values)\.mocks('make')\.run()Full ExampleThere is a full Django application in theexamples/usersfolder. It shows how
to configuredjango_mock_queriesin your tests and run them with or without
setting up a Django database. Running the mock tests without a database can be
much faster when your Django application has a lot of database migrations.To run your Django tests without a database, add a new settings file, and callmonkey_patch_test_db(). Use a wildcard import to get all the regular settings
as well.# settings_mocked.pyfromdjango_mock_queries.mocksimportmonkey_patch_test_dbfromusers.settingsimport*monkey_patch_test_db()Then run your Django tests with the new settings file:./manage.py test --settings=users.settings_mockedHere's the pytest equivalent:pytest --ds=users.settings_mockedThat will run your tests without setting up a test database. All of your tests
that use Django mock queries should run fine, but what about the tests that
really need a database?ERROR: test_create (examples.users.analytics.tests.TestApi)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/.../examples/users/analytics/tests.py", line 28, in test_create
    start_count = User.objects.count()
  [...]
NotSupportedError: Mock database tried to execute SQL for User model.If you want to run your tests without a database, you need to tell Django
to skip the tests that need a database. You can do that by putting a skip
decorator on the test classes or test methods that need a database.@skipIfDBFeature('is_mocked')classTestApi(TestCase):deftest_create(self):start_count=User.objects.count()User.objects.create(username='bob')final_count=User.objects.count()self.assertEqual(start_count+1,final_count)Installationpipinstalldjango_mock_queriesContributingAnything missing or not functioning correctly? PRs are always welcome! Otherwise, you can create an issue so someone else does it when time allows.You can follow these guidelines:Fork the repo from this pageClone your fork:gitclonehttps://github.com/{your-username}/django-mock-queries.gitcddjango-mock-queries
gitcheckout-bfeature/your_cool_featureImplement feature/fixAdd/modify relevant testsRun tox to verify all tests and flake8 quality checks passtoxCommit and push local branch to your origingitcommit.-m"New cool feature does this"gitpush-uoriginHEADCreate pull requestTODOAdd docs as a service like readthedocs with examples for every featureAdd support for missing QuerySet methods/Field lookups/Aggregation functions:Methods that return new QuerySets:annotate,reverse,none,extra,rawMethods that do not return QuerySets:bulk_create,in_bulk,as_managerField lookups:searchAggregation functions:StdDev,Variance