1

I have a model with a post-save method that I don’t want to run in test:

class MyModel(models.Model):

    def save(self, *args, **kwargs):
        super(MyModel, self).save(*args, **kwargs)
        self.post_save_method()

    def post_save_method(self):
        print("oh no!")
        return "real value"

If I make a normal test everything works as I would expect. I can patch the method, and see that I get the mocked return value, and that the post_save_method does not run (nothing is printed from this method to the console):

from django.test import TestCase
from .models import MyModel
from unittest.mock import patch

class TestMakeObjectNormally(TestCase):

    @patch.object(MyModel, 'post_save_method')
    def test_something(self, post_save_mock):
        post_save_mock.return_value = "mocked value"
        my_model = MyModel.objects.create()
        print(my_model.post_save_method())

But the way the tests are set up is that the instance is created in a superclass. Following this gist I tried to patch at a class level:

class BaseTest(TestCase):
    def setUp(self):
        self.my_model = MyModel.objects.create()

@patch.object(MyModel, 'post_save_method')
class TestMakeObjectInSuper(BaseTest):

    def setUp(self):
        super().setUp()

    def test_something(self, post_save_mock):
        post_save_mock.return_value = "mocked value"
        print(self.my_model.post_save_method())

This works in that the post_save_method return value is the mocked one, but unfortunately I can see that the method is running (“oh no!” is printed to the console).

(I also tried patching both setUp() methods and the base class)

Any advice appreciated!

Derek Hill
  • 5,965
  • 5
  • 55
  • 74

0 Answers0