I am having a difficult time setting test session variables for unit testing some Flask views. There are "email" and "display name" session variables that are normally set via code that handles Google Oauth2 login stuff. My goal is to let the unit testing tools set those session variables instead. That way, my Flask endpoints can be tested independently of the whole oauth2 business.
Here's what I've tried so far. I wrote a separate "number incrementer" mini-project to isolate the issue. Here's the stack trace from running the unit test.
Error
Traceback (most recent call last):
File "/home/myusername/PycharmProjects/FlaskTestingStuff/MyFlaskTest.py", line 12, in testNumberIncrease
self.assertTrue(res is not None)
File "/usr/lib/python3.4/contextlib.py", line 66, in __exit__
next(self.gen)
File "/usr/local/lib/python3.4/dist-packages/flask/testing.py", line 94, in session_transaction
self.cookie_jar.extract_wsgi(c.request.environ, headers)
File "/usr/local/lib/python3.4/dist-packages/flask/ctx.py", line 386, in __exit__
self.auto_pop(exc_value)
File "/usr/local/lib/python3.4/dist-packages/flask/ctx.py", line 374, in auto_pop
self.pop(exc)
File "/usr/local/lib/python3.4/dist-packages/flask/ctx.py", line 341, in pop
self.app.do_teardown_request(exc)
File "/usr/local/lib/python3.4/dist-packages/flask/app.py", line 1710, in do_teardown_request
bp = _request_ctx_stack.top.request.blueprint
AttributeError: 'NoneType' object has no attribute 'request'
Here's the view for my number incrementing "mini project" flask app.
from flask import Flask, session, request
app = Flask(__name__)
app.secret_key = "somedumbkey"
@app.route("/increasenum", methods=["GET"])
def increase_num():
if session and "last_num" in session:
num = session["last_num"]
num = str(int(num) + 1)
session["last_num"] = num
return num
else:
session["last_num"] = "0"
return "0"
if __name__ == '__main__':
app.run(debug=True)
Lastly, here is the unit test that's giving me a hard time.
import unittest
from flaskapp import app
from flask import session
class FlaskTestCase(unittest.TestCase):
def testNumberIncrease(self):
with app.test_client() as client:
with client.session_transaction() as sess:
sess["last_num"] = "8"
res = client.get("/increasenum")
self.assertTrue(res is not None)
if __name__ == '__main__':
unittest.main()
Does anybody have any ideas on how to properly set up "mock session variables" properly for these kinds of unit tests?
The indentation is wrong. The session should be modified in the session_transaction()
block, but the request should be sent after that block has ended. Unindent res = client.get()
by one level.
import unittest
from flaskapp import app
from flask import session
class FlaskTestCase(unittest.TestCase):
def testNumberIncrease(self):
with app.test_client() as client:
with client.session_transaction() as sess:
# Modify the session in this context block.
sess["last_num"] = "8"
# Test the request in this context block.
res = client.get("/increasenum")
self.assertTrue(res is not None)
if __name__ == '__main__':
unittest.main()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With