How to test delete instance in Django

Running Django, I have a view to delete logged-in user on POST request.

@login_required
def delete_user(request):
    """Delete user from DB."""
    if request.method == "POST":
        get_object_or_404(User, pk=request.user.pk).delete()
        messages.success(request, _("User deleted!"), extra_tags="success")
        return redirect("home")
    return render(request, "accounts/delete-user.html")

HTML form is:

            <form method="POST" name="delete-user-form" id="delete-user-form">
                {% csrf_token %}
                <button class="mt-4 btn btn-danger" name="delete-user-btn" id="delete-user-btn" type="submit">{% translate "Delete my profile" %}</button>
            </form>

My test class with user:

class ViewsWithLoggedInUserTest(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        User.objects.create_user(
            email="test@test.com",
            password="test",
            first_name="TestFirstName",
            last_name="TestLastName",
            hometown="Kiev",
            facebook_link="https://www.facebook.com/profile.php?id=1000",
            contacts="+380991111111",
            start_coordinates="50.45, 30.52",
            avatar="avatar/default_avatar.jpg",
        )
    def setUp(self):
        self.user = User.objects.get(email="test@test.com")
        self.client.force_login(user=self.user)
        print("setUp")

    def test_delete_user_post(self):
        """Test delete user post."""
        response = self.client.post(path=reverse("delete_user"))
        self.assertFalse(self.user)
        self.assertEqual(response.status_code, 302)
        self.assertRedirects(response, expected_url=reverse("home"))

I can not undrstand how to test this function, my test_delete_user_post gives me

AssertionError: <User: test@test.com> is not false

It's not working because the variable self.user still holds the previously assigned value.

Use the refresh_from_db() method to update the variable with fresh value.

Also, to test deletion, you have to test if the DoesNotExist exception is raised or not. Testing using assertFalse will not work.

Code example:


def test_delete_user_post(self):
        response = self.client.post(path=reverse("delete_user"))
        
        with self.assertRaises(User.DoesNotExist):
            # Django will try to fetch the new value from the database
            # but since it's been deleted, DoesNotExist exception
            # will be raised
            self.user.refresh_from_db()

        ...


A (less complex/ more obvious?) alternative to xyres' answer

# setUp created self.user which this test should delete ...
def test_delete_user_post(self):
    response = self.client.post(path=reverse("delete_user"))
    self.assertFalse( User.objects.filter( pk=self.user.pk).exists() )
Back to Top