l0b0
l0b0

Reputation: 58768

How to pass context when testing deletion of an instance?

I've got a couple models, Car and CertifyRequest. When a Car instance is created, modified or deleted I need to create a CertifyRequest, which in turn needs to be manually approved. The CertifyRequest instance contains the time it was created.

I've tested creating and modifying by injecting context={"now": …} into a CarSerializer instance, but I can't figure out how to do the equivalent when deleting:

  1. Delete requests are never passed to the serializer, so I can't access the context in the same way.
  2. I can override destroy in the ModelViewSet and use get_serializer_context within it, but
    1. I can't seem to pass the serializer to the ModelViewSet instance and
    2. the implementation returns a completely different context anyway.
  3. I do not want to use a horrible hack like an optional query parameter or testing that the time is "close to" the current test client time.

The hack I'm using currently is to set an extra now property on the Request which I pass to the view, and to look for that inside destroy.

Upvotes: 0

Views: 77

Answers (1)

A. J. Parr
A. J. Parr

Reputation: 8026

If you're using Django's timezone.now() in your view to get the current time, you can mock that method to return a specific time in your tests and assert against that.

def test_destroy_car():
    client = APIClient()
    @mock.patch("application.views.timezone.now") as now:
        destroy_time = datetime.datetime(2019, 4, 23, 11, 2, 0)
        now.return_value = destroy_time
        response = client.destroy("/api/car/12345/")
        assert response.status_code == status.HTTP_204_NO_CONTENT, "The request to delete did not return a 204 response"
        certify_request = CertifyRequest.objects.order_by("id").last()
        assert certify_request.created_at == destroy_time, "CertifyRequest destroy time is incorrect"

Upvotes: 1

Related Questions