2015-05-07 4 views
1

Я пишу модульные тесты для класса client_py , который запрашивает API. Каждый тест создает экземпляр клиента с c = client.Client("apikey"). Запуск одного теста за один раз отлично работает, но все они выполняются (например, с py.test). Я получаю 401: «Исключение: ответ 401: неавторизованный доступ. Запросы должны содержать действительный api-ключ».Python unittest высмеивает ключ API

У меня есть действительный ключ API, но это не должно быть включено в модульные тесты. Я был бы признателен за объяснение причин, почему "apikey" работает только для одного запроса. Более конкретно, как я могу высмеять вызовы API? Ниже приводится тестовый пример блок:

def testGetContextReturnFields(self): 
    c = client.Client("apikey") 
    contexts = c.getContext("foo") 

    assert(isinstance(contexts[0]["context_label"], str)) 
    assert(contexts[0]["context_id"] == 0) 
+1

Что и как вы издеваться сильно зависит от внутренности класса «Клиент». В конце концов, вы * можете * просто высмеять 'Client.getContext', чтобы вернуть что-то исправленное, но тогда вы только проверяете, что вы настроили макет, чтобы он соответствовал ожидаемому результату. – chepner

+0

Я не уверен, правильно ли я понимаю: вы бы хотели протестировать «Клиент» по телефону? Вы должны доверять API (вы не можете проверить API еще раз) и просто проверить, правильно ли ваш клиент делает правильные звонки. –

+0

@ Micheled'Amico, как я могу проверить свой клиент, делает правильные запросы API без фактического запроса API? – BoltzmannBrain

ответ

1

Отдельные из тестов для вызовов API и для метода Client.getContext(). Для явного тестирования вызовов API, залатать объект запроса ...

import client 
import httpretty 
import requests 
from mock import Mock, patch 
... 
def testGetQueryToAPI(self): 
    """ 
    Tests the client can send a 'GET' query to the API, asserting we receive 
    an HTTP status code reflecting successful operation. 
    """ 
    # Arrange: patch the request in client.Client._queryAPI(). 
    with patch.object(requests, 'get') as mock_get: 
    mock_get.return_value = mock_response = Mock() 
    mock_response.status_code = 200 

    # Act: 
    c = client.Client() 
    response = c._queryAPI("path", 'GET', {}, None, {}) 

    # Assert: 
    self.assertEqual(response.status_code, 200) 

# Repeat the same test for 'POST' queries. 

И для тестирования getContext(), издеваться вне HTTP с httpretty ...

@httpretty.activate 
def testGetContextReturnFields(self): 
    """ 
    Tests client.getContext() for a sample term. 
    Asserts the returned object contains the corrcet fields and have contents as 
    expected. 
    """ 
    # Arrange: mock JSON response from API, mock out the API endpoint we expect 
    # to be called. 
    mockResponseString = getMockApiData("context_foo.json") 
    httpretty.register_uri(httpretty.GET, 
         "http://this.is.the.url/query", 
         body=mockResponseString, 
         content_type="application/json") 

    # Act: create the client object we'll be testing. 
    c = client.Client() 
    contexts = c.getContext("foo") 

    # Assert: check the result object. 
    self.assertTrue(isinstance(contexts, list), 
    "Returned object is not of type list as expected.") 
    self.assertTrue(("context_label" and "context_id") in contexts[0], 
    "Data structure returned by getContext() does not contain" 
    " the required fields.") 
    self.assertTrue(isinstance(contexts[0]["context_label"], str), 
    "The \'context_label\' field is not of type string.") 
    self.assertEqual(contexts[0]["context_id"], 0, 
    "The top context does not have ID of zero.")