2013-08-02 11 views
7

Jestem nowy Mock i piszę badanej jednostki dla tej funkcji:Django unittest i szydząc moduł wnioski

# utils.py 
import requests  

def some_function(user): 
    payload = {'Email': user.email} 
    url = 'http://api.example.com' 
    response = requests.get(url, params=payload)  

    if response.status_code == 200: 
     return response.json() 
    else: 
     return None 

używam Michael Foord's Mock bibliotekę jako część mojego badanej jednostki i mam trudności drwi z response.json() zwrócić strukturę JSON. Oto mój test jednostkowy:

# tests.py 
from .utils import some_function 

class UtilsTestCase(unittest.TestCase): 
    def test_some_function(self): 
     with patch('utils.requests') as mock_requests: 
      mock_requests.get.return_value.status_code = 200 
      mock_requests.get.return_value.content = '{"UserId":"123456"}' 
      results = some_function(self.user) 
      self.assertEqual(results['UserId'], '123456') 

Próbowałem wielu kombinacji różnych ustawień próbnych po przeczytaniu dokumentów bez powodzenia. Gdybym wydrukować results w moim badanej jednostki zawsze wyświetla następujące zamiast struktury danych json chcę:

<MagicMock name=u'requests.get().json().__getitem__().__getitem__()' id='30315152'> 

przemyślenia na temat tego, co robię źle?

Odpowiedz

13

Łata json Metoda zamiast content. (content nie jest używany w some_function)

Spróbuj użyć następującego kodu.

import unittest 

from mock import Mock, patch 

import utils 

class UtilsTestCase(unittest.TestCase): 
    def test_some_function(self): 
     user = self.user = Mock() 
     user.email = '[email protected]' 
     with patch('utils.requests') as mock_requests: 
      mock_requests.get.return_value = mock_response = Mock() 
      mock_response.status_code = 200 
      mock_response.json.return_value = {"UserId":"123456"} 
      results = utils.some_function(self.user) 
      self.assertEqual(results['UserId'], '123456') 
+0

Wielkie dzięki za tę odpowiedź. Teraz działa tak, jak się spodziewałem. –

+0

Jeszcze jeden test asercji, który chciałbym dodać do testu jednostkowego, to zapewnienie wywołania metody request.get z oczekiwanymi parametrami. Coś w rodzaju 'mock_get.assert_called_with ('http://api.example.com', payload = {'Email': self.user.email}'. To zapewnia, że ​​twój kod biblioteki wywołuje żądanie z oczekiwanymi parametrami, co jest tak samo ważne, jak testowanie wartości zwracanej przez kod biblioteki, która jest wyśmiewana. – adam

1

Kolejny wzór Lubię używać który jest nieco bardziej wielokrotnego użytku byłoby uruchomić patcher w setUp metodą testu urządzenia. Ważne jest również, aby sprawdzić, czy makiety wniosek został wywołany z oczekiwanymi parametrami:

class UtilsTestCase(TestCase): 

    def setUp(self): 
     self.user = Mock(id=123, email='[email protected]') 

     patcher = patch('utils.requests.get') 
     self.mock_response = Mock(status_code=200) 
     self.mock_response.raise_for_status.return_value = None 
     self.mock_response.json.return_value = {'UserId': self.user.id} 
     self.mock_request = patcher.start() 
     self.mock_request.return_value = self.mock_response 

    def tearDown(self): 
     self.mock_request.stop() 

    def test_request(self): 
     results = utils.some_function(self.user) 

     self.assertEqual(results['UserId'], 123) 

     self.mock_request.assert_called_once_with(
      'http://api.example.com' 
      payload={'Email': self.user.email}, 
     ) 

    def test_bad_request(self): 
     # override defaults and reassign 
     self.mock_response.status_code = 500 
     self.mock_request.return_value = self.mock_response 
     results = utils.some_function(self.user) 

     self.assertEqual(results, None) 

     self.mock_request.assert_called_once_with(
      'http://api.example.com' 
      payload={'Email': user.email}, 
     ) 
0

Innym sposobem, który moim zdaniem jest bardziej przejrzysta i prosta:

import unittest 

from mock import Mock, patch 

import utils 

class UtilsTestCase(unittest.TestCase): 
    def test_some_function(self): 
     mock_response = Mock() 
     mock_response.status_code = 200 
     mock_response.json.return_value = {"UserId": "123456"} 
     with patch('utils.requests.get') as mock_requests: 
      results = utils.some_function(self.user) 
      self.assertEqual(results['UserId'], '123456')