Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - How to mock an instance inside a view

I'm testing my views and I need to make some assertions to a context dictionary before sending it to the HttpResponse object to make sure my view is making calculations as I expect. But how can I assert things? Here is an example of what I am trying to do in the view:

# some_app/views.py
def my_view(request):
    context = RequestContext(request)

    if request.GET.get('something'):
        value = # calculate the value somehow
        context.update(some_value=value)

    elif request.GET.get('something_else'):
        value = # calculate the value in other way
        context.update(some_value=value)
    # other stuff the view does

    return render_to_response('some_template.html', context_instance=context)

It occurs to me that maybe I could patch the view to have the context instance:

# some_app/tests/unit/test_myview.py
from some_app import views
from mock import patch
from django.test.client import RequestFactory


class MyTest(TestCase):
    def test_my_view(self):
        request = RequestFactory().get('some_url', data={
            'param1': 'a',
            'param2': 'b'
        })
        with patch('some_app.views', [WHAT DO I INCLUDE HERE?]) as context:
            # by now, <context> should be the context instance created in the view
            response = views.my_view(request)
            self.assertTrue(context['some_value']['value1'])
            self.assertFalse(context['some_value']['value2'])
            self.assertRaises(IndexError, some_function,
                              context['some_value']['value1'])

but I can't come up with a working ideas :(

Is there any way that, in my test, I can have available the context instance that I created in my view?

Thanks for any help :)

P.S. In-browser testing or checking the generated html is not an option in this case :(

like image 729
Gerard Avatar asked May 29 '26 01:05

Gerard


1 Answers

You can test context via response.context_data if you are using TemplateResponse. Try:

# some_app/views.py
from django.template.response import TemplateResponse

def my_view(request):
    context = {}

    if request.GET.get('something'):
        value = # calculate the value somehow
        context.update(some_value=value)

    elif request.GET.get('something_else'):
        value = # calculate the value in other way
        context.update(some_value=value)
    # other stuff the view does

    return TemplateResponse(request, 'some_template.html', context)

Tests:

# some_app/tests/unit/test_myview.py
from some_app import views
from django.test.client import RequestFactory

class MyTest(TestCase):
    def test_my_view(self):
        request = RequestFactory().get('some_url', data={
            'param1': 'a',
            'param2': 'b'
        })

        response = views.my_view(request)
        self.assertTrue(response.context_data['some_value']['value1'])
        self.assertFalse(response.context_data['some_value']['value2'])
        self.assertRaises(IndexError, some_function,
                              response.context_data['some_value']['value1'])
like image 53
Konrad Hałas Avatar answered May 30 '26 14:05

Konrad Hałas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!