Inkonsistentes Verhalten zwischen dem realen Sitzungsspeicher von Flask und test_request_context während TestsPython

Python-Programme
Guest
 Inkonsistentes Verhalten zwischen dem realen Sitzungsspeicher von Flask und test_request_context während Tests

Post by Guest »

Ich verwende den Sitzungsspeicher von Flask, um vorübergehend eine Liste von Datenklassenobjekten zu speichern. Hier ist ein Beispiel der Transaction-Klasse und meines TransactionMemoryRepository:

Code: Select all

@dataclass
class Transaction:

transaction_date: datetime.date
amount: decimal.Decimal
concept: str
Das Repository verfügt über Methoden zum Speichern und Abrufen von Transaktionen aus der Sitzung:

Code: Select all

from flask import session

class TransactionMemoryRepository:

@staticmethod
def save_transactions(transactions: list[Transaction]):
session['transactions'] = transactions

@staticmethod
def get_transactions() -> list[Transaction]:
tmp_transactions = session.get('transactions', [])
transactions = []

for tmp_transaction in tmp_transactions:
transaction = Transaction(
transaction_date=datetime.strptime(tmp_transaction['transaction_date'], '%a, %d %b %Y %H:%M:%S %Z'),
amount=Decimal(tmp_transaction['amount']),
concept=tmp_transaction['concept'],
category=tmp_transaction.get('category'),
id=tmp_transaction.get('id')
)
transactions.append(transaction)

return transactions

Das Problem besteht darin, dass der Sitzungsspeicher von Flask in der realen Ausführung die Liste der Transaktionsobjekte als Liste von Wörterbüchern speichert. Aus diesem Grund muss ich beim Lesen aus der Sitzung jedes Wörterbuch wieder einem Transaktionsobjekt zuordnen.
Bei Tests mit test_request_context ist das Verhalten jedoch anders:
Die Sitzung speichert die Objekte als tatsächliche Transaktionsinstanzen
, was dazu führt, dass die Lesemethode mit dem folgenden Fehler fehlschlägt:

Code: Select all

TypeError: 'Transaction' object is not subscriptable
Hier ist mein Testaufbau mit pytest:

Code: Select all

    @pytest.fixture
def flask_app():
app = Flask(__name__)
app.secret_key = "test_secret_key"
return app

@pytest.fixture
def flask_request_context(flask_app):
with flask_app.test_request_context():
yield
Dann verwende ich dieses Gerät für meinen Test:

Code: Select all

        def test_save_and_get_transactions(self, flask_request_context):

transactions = [
Transaction(amount=Decimal(100), concept="Concept 1",
transaction_date=datetime.now()),
Transaction(amount=Decimal(200), concept="Concept 2",
transaction_date=datetime.now())
]

TransactionMemoryRepository.save_transactions(transactions)

result = TransactionMemoryRepository.get_transactions()

#asserts ...
Das Problem: In der Produktion wird session['transactions'] zu einer Liste von Wörterbüchern, aber während Tests speichert es tatsächliche Transaktionsobjekte. Infolgedessen funktioniert die Methode get_transactions() in der realen Anwendung einwandfrei, schlägt jedoch in Tests fehl, da ich auf Attribute zugreife, als wären sie Wörterbücher.
Frage:
Warum gibt es einen Unterschied zwischen dem Verhalten der Flask-Sitzung während der tatsächlichen Ausführung und in Tests mit test_request_context?
Wie kann ich sicherstellen, dass sich die Sitzung in beiden Umgebungen gleich verhält? das mein Tests spiegeln das tatsächliche Verhalten wider?
Die vorübergehende Lösung ist vorerst die Zuordnung zu einem Diktat beim Speichern, aber das ist eine Problemumgehung.
I' Ich hänge zwei Bilder an, um die Debugging-Ergebnisse zu zeigen. Sie können sehen, dass die Sitzung während der normalen Ausführung ein Transaktionsobjekt mit ordnungsgemäß typisierten Attributen zurückgibt, während sie während der Tests ein Diktat zurückgibt.
Image

Image

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post