Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testes de modelos envolvendo datetimes #251

Closed
dunossauro opened this issue Oct 3, 2024 · 2 comments
Closed

Testes de modelos envolvendo datetimes #251

dunossauro opened this issue Oct 3, 2024 · 2 comments

Comments

@dunossauro
Copy link
Owner

Faz um tempo que ando pensando em qual a melhor forma de resolver esse problema. Embora ele não seja exatamente complexo, a manipulação de variáveis com func.now() podem ser bastante problemáticas se você não souber o mínimo sobre mocks ou sobre monkeypatch [assuntos que não foram cobertos no curso].

O que acabou por deixar diversas dúvidas na resolução dos exercícios. O freezegun apresenta alguns problemas pra mockar as funções que envolvem o sqlalchemy. Realizei alguns testes com time-machine, obtive maiores sucessos.

Porém, após refletir bastante, acredito que seria de GRANDE valia ensinar os hooks de eventos do SQLAlchemy, embora usaremos só nos testes, isso pode ficar como um aprendizado para o futuro das pessoas que fizerem o curso.

@contextmanager
def mock_db_time(*, model, time=datetime(2024, 1, 1)):
    def mock(mapper, connection, target):
        if hasattr(target, 'created_at'):
            target.created_at = time
        if hasattr(target, 'updated_at'):
            target.updated_at = time

    event.listen(model, 'before_insert', mock)

    yield time

    event.remove(model, 'before_insert', mock)

O que me parecia complexo nessa implementação antes seria juntar tanto o freezegun, quanto os eventos. Tudo ao mesmo tempo tende a ser bastante problemático. Mas acredito que o impacto não deva ser tão grande, afinal, já temos um gerenciador de contexto no curso.

O efeito nos testes parece ser bem pequeno:

def test_create_user(session):
    with mock_db_time(model=User) as time:
        new_user = User(
            username='alice', password='secret', email='teste@test'
        )
        session.add(new_user)
        session.commit()

        user = session.scalar(select(User).where(User.username == 'alice'))

    assert user.username == 'alice'
    assert user.created_at == time

Considerando que esse bloco with seja usado somente em momentos específicos, não seria necessária nem mesmo a interferência com o freezegun ou time-machine.

Isso poderia melhorar o teste da aula 04 e também todas às vezes em que for necessário fazer um fullmach nos testes.

A aula 09 se beneficia em todos os exercícios, principalmente os de schemas do pydantic.

Referência para os eveitos de mapeamento: https://docs.sqlalchemy.org/en/20/orm/events.html#mapper-events

@dunossauro
Copy link
Owner Author

Se for implementado assim, fecha grande parte dos tópicos envolvidos em #236

dunossauro added a commit that referenced this issue Oct 4, 2024
…olvendo datas.

Conteúdo da aula 04 que modifica o código fonte de todas as aulas seguintes

related #251
@dunossauro
Copy link
Owner Author

fechado por #252

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant