joe
joe

Reputation: 9503

mocking - request and the response inside django rest fbv

I have 3 players.
1. client : Any mobile devices
2. poink: Django server
3. platform: Another server

The mechanic is
1. client POST to poink
2. poink GET to platform
3. platform response back to poink
4. poink responses back to client

views.py https://gist.github.com/elcolie/111fde80317e96523a34bb297e5ccf25
tests.py https://gist.github.com/elcolie/565b458716dbf5358d2ad7ba1ff2ee6b
output.txt https://gist.github.com/elcolie/9a93d5fc5237b403b4d1d2c8ee3c352e

Goal:
I want to run integration test on this endpoint, but I do not want to shoot the real endpoint

Reads:
python mock Requests and the response
Python mock, django and requests
mocking functions using python mock
http://engineroom.trackmaven.com/blog/real-life-mocking/

Problem:
It is not mock my object. It raises the error you can see from output.txt

Workaround:
I do not know what is the best practice on this integration test. But I do more simplification on it.

  1. Let the login function be a plain function
  2. request is created in the test environment
  3. patch the function requests.get

Here is the confirmed code. Thanks to Andrew Backer

def test_mobile_send_wrong_session_key(db):
    from rest_framework.test import APIRequestFactory
    factory = APIRequestFactory()
    url = reverse('auth:login')
    data = {'session_key': 'Wrong value'}
    request = factory.post(url, data)
    from poinkbackend.apps.authentications.views import login
    with patch('requests.get') as mock_get:
        # `Platform` response with 400 to `Poink`
        mock_get.return_value.ok = False
        mock_get.return_value.status_code = 400
        mock_get.return_value.text = 'Bad Request El'
        res = login(request)
    assert 406 == res.status_code

Reference:
https://realpython.com/blog/python/testing-third-party-apis-with-mocks/

Upvotes: 1

Views: 2689

Answers (2)

SebCorbin
SebCorbin

Reputation: 1733

Your endpoint mock is ok, but the test you are running is trying to set something in the database. That gives two choices:

  • either you mock the database too
  • or you can use a django TestCase that will spawn a test database, and delete it at the end of the test

Upvotes: 1

joe
joe

Reputation: 9503

I do not know what is the best practice on this integration test. But I do more simplification on it.

  1. Let the login function be a plain function
  2. request is created in the test environment
  3. patch the function requests.get

Reference:
https://realpython.com/blog/python/testing-third-party-apis-with-mocks/

def test_mobile_send_wrong_session_key(db):
    from rest_framework.test import APIRequestFactory
    factory = APIRequestFactory()
    url = reverse('auth:login')
    data = {'session_key': 'Wrong value'}
    request = factory.post(url, data)
    from poinkbackend.apps.authentications.views import login
    with patch('requests.get') as mock_get:
        # `Platform` response with 400 to `Poink`
        mock_get.return_value.ok = False
        mock_get.return_value.status_code = 400
        mock_get.return_value.text = 'Bad Request El'
        res = login(request)
    assert 406 == res.status_code

Upvotes: 0

Related Questions