2

I'd like to test a form without the tests hitting the database. The form references a Model using a ModelChoiceField which in turn runs a query during form.is_valid() that tries to fetch the referenced object from the database. This happens in related_object_field.to_python() which tries to get the object from the default manager's QuerySet.

I tried patching my model's queryset.get() but to no avail:

@patch('myapp.models.MyModel._default_manager.get_queryset')
def test_form(mocked_get_queryset):
    assert mocked_get_queryset.called  # <-- this assertion fails
    [...]
    form = MyForm(data=my_data)
    assert form.is_valid()

This is a snippet of the traceback which shows why the database is hit and what I'd like to have mocked:

    form.is_valid()
django/forms/forms.py:179: in is_valid
    return self.is_bound and not self.errors
django/forms/forms.py:174: in errors
    self.full_clean()
django/forms/forms.py:376: in full_clean
    self._clean_fields()
django/forms/forms.py:394: in _clean_fields
    value = field.clean(value)
django/forms/fields.py:148: in clean
    value = self.to_python(value)
django/forms/models.py:1245: in to_python
    value = self.queryset.get(**{key: value})
[...]
E       Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.

I guess that I'm not patching the right place. Can you give me any hints on how to mock the database call?

jnns
  • 5,148
  • 4
  • 47
  • 74

0 Answers0