Search code examples
pythondjangounit-testingdjango-rest-frameworkmocking

I am using python @mock.patch decorator, I want to set return_value of a query like model.objects.filter. How to set the return_value for such query


For eg. my model

class Mymodel(models.Model):
  name = models.CharField()
  age = models.IntegerField()

For eg. In my View I am using this model as

class MyView(generics.ListAPIView):
  serializerClass = MySerrializer
  
  def get(self, req, *args, **kwargs):
    res = Mymodel.objects.filter(age=25)
    serializer = self.get_serializer(res, many=true)
    return Response(serializert.data)

Now For eg. I am writing a test case for that View

@mock.patch('views.Mymodel.objects.filter')
def test_MyView(filtered_result):
  filtered_result.return_value = ???

Now How should I set the return Value, if it was a Mymodel.objects.get I would have set like this

filtered_result.return_value = Mymodel(name="xyz", age=30)

Now for Mymodel.objects.filter Do I have to pack some Mymodel instances in django QuerySet ?


Solution

  • To do that you can create a fake model before patching, supposing that you haven't any data for testing, you can create a new model instance for the filter:

    class FakeModel:
        @staticmethod
        def filter():
            return Mymodel.objects.create(name="xyz", age=30)
    
    

    And then pass this FakeModel to your patch as return_value=FakeModel().

    So you will have that value passed for the mock_my_model variable.

    At the end, you can pass this mock_my_model variable to the mock_my_model.filter.return_value.

    @mock.patch(
        'apis.views.Mymodel.objects.filter',
        return_values=FakeModel(),
    )
    def test_MyView(mock_my_model):
      mock_my_model.filter.return_value = mock_my_model
      ...