zanderle
zanderle

Reputation: 825

Can't mock a model's method in Django tests

I want to mock one of the model's methods in my tests. This is my model with the method I want to mock

class Customer(models.Model):
    # Fields ...

    def save(self, *args, **kwargs):

        update_collector = self.id is None

        super(Customer, self).save(*args, **kwargs)

        if update_collector:
            self.send_to_address_book()

    def send_to_address_book(self):  # This is the method I want mocked
        email = self.user.email
        first_name = self.user.first_name
        last_name = self.user.last_name
        print("This is not being mocked")

        investigate_customer.apply_async(
            args=[first_name, last_name, email]
        )

Then, I want all the tests that inherit from CustomerTestCase to mock send_to_address_book

class CustomerTestCase(object):
    @mock.patch('accounts.models.Customer.send_to_address_book')
    def create_user_and_customer(self, name, mock_method):
        mock_method.return_value = None
        if not name:
            name = 'test'
        email = name + '@test.si'
        user = User.objects.create_user(name, email)
        customer = Customer.objects.create(user=user)
        return user, customer

However, when I run the following tests, send_to_address_book is not mocked.

class CustomerQueriesTest(CustomerTestCase, TestCase):
    def setUp(self):
        G(Language, code='en', name='English')
        self.user, self.customer = self.create_user_and_customer()

    def test_queries_running(self):
        profile = self.user.profile
        resp = self.user.profile.queries_running()
        self.assertEqual(resp, 0)
        G(Package)  # using Django dynamic fixtures to create a new Package

What am I missing?

Upvotes: 4

Views: 1773

Answers (1)

zanderle
zanderle

Reputation: 825

So, I found what was the issue.

Partly, it was the problem of default settings of DDF - if a model field is blank/null it will still fill it by default. So when a Package was created with DDF, it also created a Customer because of a FK.

The second part of the problem was, that Package is in a different module than Customer so @mock.patch('accounts.models.Customer.send_to_address_book') did nothing (see Python docs for more details). I had to add a second patch, which took care of when a Customer was created through Package:

@mock.patch('billing.models.Customer.send_to_address_book')

Upvotes: 5

Related Questions