Django unit test mock queryset from related object

I have the following function:

import unittest from unittest import mock def get_payments(order): return order.payments.filter(status='complete').order_by('-date_added) 

I want to make fun of the filter and order_by methods to check the arguments that are being called.

I tried:

 class TestPayments(unittest.TestCase): @mock.patch('path.Order.payments.filter.order_by') @mock.patch('path.Order.payments.filter') def test_get_payments(self, mock1, mock2): mock1.assert_called_with(status='complete') mock2.assert_called_with('-date_added') 

Another layout I tried:

 @mock.patch('path.Payment.objects.filter.order_by') @mock.patch('path.Payment.objects.filter') @mock.patch('path.Order.payments.objects.filter.order_by') @mock.patch('path.Order.payments.objects.filter') 

In the last two mocks, I have an error that path.Order does not exist. I have already used the direct layout for a request of type Payment.objects.filter() and it works, but starting with a sister model of type Order I have failed.

The connection between Order and Payment is, as you expect, from one to many.

+5
source share
2 answers

With mocking objects, I solved it.

  order = MagicMock(side_effect=Order()) order.payments.filter.return_value = MagicMock(side_effect=Payment.objects.filter(id=0)) order.payments.filter.return_value.order_by.return_value = [Payment()] order.payments.filter.assert_called_with(status='complete') order.payments.filter.return_value.order_by.assert_called_with('-date_updated') 
+2
source

To explain what happens here: QuerySet methods such as filter() , exclude() , order_by() , etc., return a QuerySet, so you can bind them.

At first you tried to fix the methods as if they were in a package hierarchy. What you ended up with was not fixing the method, but making fun of the return value for each method with a binding on how to do it.

Unfortunately, there is no documentation on this issue. When I ran into this problem, I had some stackoverflow answers that helped me, but I can't find them again.

Similar questions (where the answers really give no explanation):

There are libraries that can help you: mock-django provides an ORM bullying class. Their approach to the mockery methods of QuerySet is quite interesting. What I personally found very useful for testing Django models, Model Mommy , because it helps you create lightweight model mockups.

+1
source

Source: https://habr.com/ru/post/1273106/


All Articles