FastDepends¶
Algumas instruções rápidas de uso básico para lidar com o FastDepends e seus testes.
Vamos imaginar uma estrutura básica:
O código fonte¶
Basicamente para que algo seja injetado, esse algo precisa ser um Callable. Esse Callable deve ser passado para outro Callable como valor default envolvido por Depends. Em conjunto a isso, quem receberá a injeção precisa ser decorado com @inject:
from fast_depends import Depends, inject
def dependencia():
yield 1
@inject
def sut(var: int = Depends(dependencia)):
"""Função que recebe a injeção e tbm é alvo dos testes."""
return var
Conftest¶
Para alterar o valor injetado durante os testes, que é o grande valor de injeção, podemos usar uma fixture única ou um grupo de fixtures.
Prefiro separar o provider em uma fixture específica, o que garante que ele sempre será limpo em relação ao escopo básico das fixtures, ou seja, por teste.
import pytest
from fast_depends import dependency_provider
from app.app import dependencia
@pytest.fixture
def provider():
"""Forma rápida de garantir que sempre será limpo a cada teste."""
yield dependency_provider
dependency_provider.clear()
Depois, cada dependência pode ser sobreescrita por uma fixture diferente, garantindo que só quem precisar daquilo alterado use:
@pytest.fixture
def override_de_dependencia(provider):
"""troca das dependências pelo que será usado nos testes."""
def dependencia_test():
yield 2
provider.override(dependencia, dependencia_test)
return dependencia_test
Já vi alguns smells relacionados a muitas sobrescritas em uma mesma fixture, o que pode ser meio delirante na hora de usar os valores.
Testes¶
Com isso as funções de testes podem usar ou não o valor retornado:
import pytest
from app.app import sut
def test_injeta_dependencia_no_sut(override_de_dependencia):
"""
Validação simples, afinal é um bypass pra mostrar a infra.
Você recebe a fixture quando precisa dela para alguma validação
ou para algum uso básico.
"""
assert sut() == override_de_dependencia
@pytest.mark.usefixtures("override_de_dependencia")
def test_injeta_mais_nao_usa():
"""
Se não precisar da fixture, pode simplesmente chamar ela.
O a injeção será sobreescrita, mas não necessáriamente
será usada pelo teste
"""
assert sut() == 2
Assim, simplificando a estrutura dos testes.