Solicitações simuladas de Python

Resumo : Neste tutorial, você aprenderá como simular o requestsmódulo em Python para testar uma chamada de API usando o módulo unittest .

O requestsmódulo é uma biblioteca HTTP que permite enviar solicitações HTTP facilmente. Normalmente, você usa o requestsmódulo para chamar uma API de um servidor remoto.

O cenário

Para fins de demonstração, usaremos uma API pública fornecida por jsonplaceholder.typicode.com :

https://jsonplaceholder.typicode.com/Linguagem de código:  Python  ( python )

Para fazer uma chamada de API, você usará o requestsmétodo para enviar um método HTTP GET para o seguinte endpoint:

https://jsonplaceholder.typicode.com/albums/1Linguagem de código:  Python  ( python )

Ele retornará dados JSON no seguinte formato:

{
  "userId": 1,
  "id": 1,
  "title": "quidem molestiae enim"
}Linguagem de código:  Python  ( python )

Como o requestsmódulo não é um módulo integrado, você precisa instalá-lo executando o seguinte comando pip:

pip install requestsLinguagem de código:  Python  ( python )

Fazendo uma chamada de API usando o módulo de solicitações

O seguinte define um novo módulo chamado album.pycom uma função find_album_by_id()que retorna um álbum por um id:

import requests


def find_album_by_id(id):
    url = f'https://jsonplaceholder.typicode.com/albums/{id}'
    response = requests.get(url)
    if response.status_code == 200:
        return response.json()['title']
    else:
        return NoneLinguagem de código:  Python  ( python )

Como funciona.

Primeiro, formate o endpoint da API que inclui o parâmetro id:

url = f'https://jsonplaceholder.typicode.com/albums/{id}'Linguagem de código:  Python  ( python )

Segundo, chame a get()função do módulo requests para obter um Responseobjeto:

response = requests.get(url)Linguagem de código:  Python  ( python )

Terceiro, chame o json()método do objeto de resposta se a chamada da API for bem-sucedida:

if response.status_code == 200:
   return response.json()['title']
else:
   return NoneLinguagem de código:  Python  ( python )

O response.json()retorna um dicionário que representa os dados JSON.

Criando um módulo de teste

Criaremos um test_album.pymódulo de teste que testa as funções do album.pymódulo:

import unittest

from album import find_album_by_id


class TestAlbum(unittest.TestCase):
   passLinguagem de código:  Python  ( python )

Zombando do módulo de solicitações

A find_album_by_id()função tem duas dependências:

  • O get()método do requestsmódulo
  • O Responseobjeto retornado pela get()função.

Então, para testar a find_album_by_id()função, você precisa:

  • Primeiro, simule o módulo de solicitações e chame a get()função ( mock_requests)
  • Segundo, simule o objeto de resposta retornado.

Em outras palavras, o arquivo mock_requests. get()retorna um objeto de resposta simulado.

Para simular o módulo de solicitações, você pode usar a patch()função. Suponha que mock_requestsseja uma simulação do requestsmódulo.

O mock_requests.get()deve retornar uma simulação para a resposta. Para simular a resposta, você pode usar a MagicMockclasse do unittest.mockmódulo.

O seguinte mostra como testar find_album_by_id()usando o test_find_album_by_id_success()método de teste:

import unittest
from unittest.mock import MagicMock, patch

from album import find_album_by_id


class TestAlbum(unittest.TestCase):

    @patch('album.requests')
    def test_find_album_by_id_success(self, mock_requests):
        # mock the response
        mock_response = MagicMock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            'userId': 1,
            'id': 1,
            'title': 'hello',
        }

        # specify the return value of the get() method
        mock_requests.get.return_value = mock_response

        # call the find_album_by_id and test if the title is 'hello'
        self.assertEqual(find_album_by_id(1), 'hello')Linguagem de código:  Python  ( python )

Como funciona.

Primeiro, corrija o requestsmódulo como o mock_requestsobjeto:

@patch('album.requests')
def test_find_album_by_id_success(self, mock_requests):
    # ...Linguagem de código:  Python  ( python )

Segundo, simule a resposta da get()função usando a MagicMockclasse. Neste método de teste, especificamos o código de status 200 e return_valueda json()função como um valor codificado:

mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
   'userId': 1,
   'id': 1,
   'title': 'hello',
}Linguagem de código:  Python  ( python )

Terceiro, use mock_response como valor de retorno da get()função:

 mock_requests.get.return_value = mock_responseLinguagem de código:  Python  ( python )

Por fim, teste se o título do álbum é igual ao que especificamos return_valueno mock_response:

self.assertEqual(find_album_by_id(1), 'hello')Linguagem de código:  Python  ( python )

Execute o teste:

python -m unittest -vLinguagem de código:  Python  ( python )

Saída:

test_find_album_by_id_success (test_album.TestAlbum) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.001s

OKLinguagem de código:  Python  ( python )

Usando a mesma técnica, você também pode testar a find_album_by_id()função no caso de falha:

import unittest
from unittest.mock import MagicMock, patch

from album import find_album_by_id


class TestAlbum(unittest.TestCase):

    @patch('album.requests')
    def test_find_album_by_id_success(self, mock_requests):
        # mock the response
        mock_response = MagicMock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            'userId': 1,
            'id': 1,
            'title': 'hello',
        }

        # specify the return value of the get() method
        mock_requests.get.return_value = mock_response

        # call the find_album_by_id and test if the title is 'hello'
        self.assertEqual(find_album_by_id(1), 'hello')

    @patch('album.requests')
    def test_find_album_by_id_fail(self, mock_requests):
        mock_response = MagicMock()
        mock_response.status_code = 400

        mock_requests.get.return_value = mock_response
        self.assertIsNone(find_album_by_id(1))Linguagem de código:  Python  ( python )

Saída:

test_find_album_by_id_fail (test_album.TestAlbum) ... ok
test_find_album_by_id_success (test_album.TestAlbum) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.002s

OKLinguagem de código:  Python  ( python )

Resumo

  • Use a patch()função para simular o módulo de solicitações ( mock_requests)
  • Use o MagicMockpara simular a resposta retornada pela mock_requests.get()função.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *