Resumo : neste tutorial, você aprenderá sobre a classe Mock mais unittest do Python e como usá-la para simular outras classes.
Introdução à classe Mock mais unittest do Python
As simulações simulam o comportamento de objetos reais. Para testar um objeto que depende de outros objetos de maneira isolada, você usa objetos simulados para simular os objetos reais.
Para simular objetos, você usa o unittest.mock
módulo. O unittest.mock
módulo fornece a Mock
classe que permite simular outros objetos.
Ele também fornece a MagicMock
classe que é uma subclasse da Mock
classe. Além dos métodos e propriedades da Mock
classe, a MagicMock
classe possui as implementações de todos os métodos dunder, por exemplo, __str__ e __repr__ .
Veja o exemplo a seguir:
from unittest.mock import Mock
# create a new mock object
mock = Mock()
# mock the api function
mock.api.return_value = {
'id': 1,
'message': 'hello'
}
# call the api function
print(mock.api())
Linguagem de código: Python ( python )
Saída:
{'id': 1, 'message': 'hello'}
Linguagem de código: Python ( python )
Como funciona.
Primeiro, importe a Mock
classe do unittest.mock
módulo:
from unittest.mock import Mock
Linguagem de código: Python ( python )
Segundo, crie uma nova instância da Mock
classe:
mock = Mock()
Linguagem de código: Python ( python )
Terceiro, simule a api()
função e atribua seu valor de retorno a um dicionário:
mock.api.return_value = {
'id': 1,
'message': 'hello'
}
Linguagem de código: Python ( python )
Finalmente, chame o api()
do objeto simulado. Ele retornará o valor atribuído:
print(mock.api())
Linguagem de código: Python ( python )
Neste exemplo, temos dois objetos simulados: mock
& mock.api
.
Vamos adicionar a print()
instrução ao programa para ver como funciona:
from unittest.mock import Mock
# create a new mock object
mock = Mock()
print(mock)
# mock the api function
mock.api.return_value = {
'id': 1,
'message': 'hello'
}
print(mock.api)
# call the api
print(mock.api())
Linguagem de código: Python ( python )
Saída:
<Mock id='1830094470496'>
<Mock name='mock.api' id='1830100086416'>
{'id': 1, 'message': 'hello'}
Linguagem de código: Python ( python )
A saída mostra dois Mock
objetos.
Resumindo, se você atribuir uma propriedade que não existe no Mock
objeto, o Python retornará um novo objeto simulado. Por causa dessa dinâmica, você pode usar a Mock
classe para simular qualquer objeto que desejar.
Quando usar simulação
Estes são os casos que você pode considerar usar mocks:
- Chamadas do sistema
- Rede
- Operação de E/S
- Relógios e hora, fusos horários
- Ou outros casos cujos resultados são imprevisíveis
Por que usar simulações
A seguir estão os benefícios das simulações:
- Acelere o teste
- Excluir redundâncias externas
- Torne previsíveis resultados imprevisíveis
Exemplo de simulação do Unittest Python
Suponha que você tenha um módulo chamado odometer.py
:
from random import randint
def speed():
return randint(40, 120)
def alert():
s = speed()
if s < 60 or s > 100:
return True
return False
Linguagem de código: Python ( python )
No módulo sensor.py:
- O
speed()
retorna a velocidade atual de um veículo. Ela retorna um valor aleatório entre 40 e 120. No mundo real, a função leria os dados do hodômetro. - A
função retorna verdadeiro se a velocidade atual for inferior a 60 km/e superior a 120 km/h. Aalert()
função usa aalert()
speed()
função para obter a velocidade atual.
Será difícil testar a alert()
função porque o valor retornado pela speed()
função varia. Para resolver isso, você pode usar Mock
class.
O seguinte cria um test_odometer.py
módulo de teste que testa a alert()
função:
test_alert_normal (test_odometer.TestOdometer) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Linguagem de código: Python ( python )
Como funciona.
Primeiro, atribua um objeto Mock à odometer.speed
função:
odometer.speed = Mock()
Linguagem de código: Python ( python )
Segundo, defina o valor de retorno da speed()
função como 70:
odometer.speed.return_value = 70
Linguagem de código: Python ( python )
Terceiro, chame a
função e teste se ela retorna False. A alert()
função chamará o objeto simulado em vez da alert()
speed()
função real.
A imagem a seguir ilustra como o teste funciona com objetos simulados:
Execute o teste:
python -m unittest test_odometer.py -v
Linguagem de código: Python ( python )
Saída:
test_alert_normal (test_odometer.TestOdometer) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Linguagem de código: Python ( python )
O seguinte adiciona os casos de teste que estão acima e abaixo da velocidade:
import unittest
from unittest.mock import Mock
import odometer
class TestOdometer(unittest.TestCase):
def test_alert_normal(self):
odometer.speed = Mock()
odometer.speed.return_value = 70
self.assertFalse(odometer.alert())
def test_alert_overspeed(self):
odometer.speed = Mock()
odometer.speed.return_value = 100
self.assertFalse(odometer.alert())
def test_alert_underspeed(self):
odometer.speed = Mock()
odometer.speed.return_value = 59
self.assertTrue(odometer.alert())
Linguagem de código: Python ( python )
Execute o teste:
python -m unittest test_odometer.py -v
Linguagem de código: Python ( python )
Saída:
test_alert_normal (test_odometer.TestOdometer) ... ok
test_alert_overspeed (test_odometer.TestOdometer) ... ok
test_alert_underspeed (test_odometer.TestOdometer) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
Linguagem de código: Python ( python )
Resumo
- Use a
Mock
classe daunittest.mock
classe para zombar de outros objetos.