Как я могу проверить функцию, указав недопустимые данные, не передавая ее в качестве входных данных для функции? - PullRequest
0 голосов
/ 23 декабря 2018

Я новичок во всей сцене тестового примера, и я решил использовать pytest и pytest-asyncio для написания своих тестовых случаев.Мне удалось выяснить, как писать тестовые случаи для базовой функциональности.например, утверждая, что когда я вызываю функцию, она возвращает ожидаемые данные.

Теперь я хотел бы написать контрольные примеры, предназначенные для сбоя, но я запутался в том, как это сделать, не меняя функции напринять неверные данные в качестве аргумента.

TL; DR Как мне написать контрольный пример для проверки get_access_token () в следующем коде с недопустимыми WOW_CLIENT_ID и WOW_CLIENT_SECRET?(Я ожидаю, что тест не пройден из-за использования неверных учетных данных)

wow_api.py (содержит функцию, которую я хочу проверить: get_access_token ())

import aiohttp
import asyncio
import os

async def get_access_token():
auth_path = 'https://us.battle.net/oauth/token'
auth_credentials = aiohttp.BasicAuth(login=os.environ.get('WOW_CLIENT_ID'), password=os.environ.get('WOW_CLIENT_SECRET'))

try:
    async with aiohttp.ClientSession(auth=auth_credentials) as client:
        async with client.get(auth_path, params={'grant_type': 'client_credentials'}) as auth_response:
            assert auth_response.status == 200
            auth_json = await auth_response.json()
            return auth_json['access_token']

except Exception as error:
    # Error receiving token:
    print('Error: Unable to retrieve auth token')
    return { 'error': 'Sorry, I was unable to retrieve authorization from Battle.net for this request.' }

test_wow_api.py (содержит контрольный пример)

import asyncio
import pytest
from wow import *

@pytest.mark.asyncio
async def test_wow_api_invalid_credentials():
    #SOMETHING PROBABLY GOES HERE TO CHANGE/FAKE THE WOW_CLIENT_ID
    access_token = await get_access_token()
    assert 'error' in access_token

1 Ответ

0 голосов
/ 24 декабря 2018

Это пример того, почему вы хотите избежать тестирования соавторов.Если вы спросите "что происходит, когда WOW_CLIENT_ID недействительно?"это подразумевает проверку поведения aiohttp.ClientSession, потому что это то, что проверяет идентификатор.Вместо этого, подумайте о том, как ClientSession может произойти сбой, когда вы используете его таким образом, запустите это поведение в своих тестах, используя внедрение зависимостей и насмешки, и проверьте, что вы обрабатываете его, как вам нужно.

Итаквместо того, чтобы создавать сеанс клиента в функции, вы можете передать его в качестве параметра:

async def get_access_token(client):
    auth_path = 'https://us.battle.net/oauth/token'
    try:
        async with client.get(auth_path, params={'grant_type': 'client_credentials'}) as auth_response:
            assert auth_response.status == 200
            auth_json = await auth_response.json()
            return auth_json['access_token']
        # etc.

И затем вы создадите объект в своем тесте, который генерирует исключение ClientSession с недопустимыми параметрами.

Вы можете создать свой фальшивый объект следующим образом:

class MockSession:
    def __init__(self):
        pass
    def get(pathname, params):
        raise aoihttp.InvalidURL

и использовать его в таком тесте, как этот

class TestAccessToken(unittest.TestCase):
    def test_handle_invalid_url(self):
        invalid_client = MockSession()
        self.assertIsNone(get_access_token(invalid_client))  # or whatever you want to happen

unittest.mock дает вам простой способнастроить это поведение без необходимости создания объекта.Например,

from unittest import mock
class TestAcccessToken(unittest.TestCase):
    def test_invalid_url(self):
        # Create a mock client that raises InvalidUrl when you call `get()` on it
        client = mock.MagicMock()
        client.get = mock.Mock(side_effect=KeyError())
        self.assertIsNone(get_access_token(client))

(Расширенные функции насмешки, вероятно, могут помочь вам без изменения кода, но обычно мне проще всего передать соавторов, как показано выше.)

...