2017-10-10 218 views
11

我正在写一个单元测试,它使用登录的用户在查询当前视图:如何设置pytest的current_user?

@app.route('/vendors/create', methods=['GET', 'POST']) 
@login_required 
def create_vendors(): 
    vendor_form = VendorForm(request.form) 
    if vendor_form.validate_on_submit(): 
     vendor = db.session.query(Vendors).filter(Vendors.name == vendor_form.name.data, 
                Vendors.users.contains(g.user)).first() 
     if vendor: 
      flash('There is a vendor with this name already.') 
      return redirect(url_for('create_vendors', vendor_form=vendor_form)) 
     vendor = Vendors(name=vendor_form.name.data, aws_access_key=vendor_form.aws_access_key.data, 
         merchant_key=vendor_form.merchant_key.data, secret_key=vendor_form.secret_key.data) 
     vendor.users.append(current_user) 
     db.session.add(vendor) 
     db.session.commit() 
     return redirect(url_for('vendors')) 
    return render_template('edit_vendor.html', vendor_form=vendor_form) 

和测试:

def test_create_vendor(self): 
    response = TestViews.client.post('/vendors/create', follow_redirects=True, 
            data=dict(name='Name', aws_access_key='aws_access_key', 
               merchant_key='merchant_key', 
               secret_key='secret_key')) 
    assert response.status_code == 200 
    vendors = db.session.query(Vendors).filter(Vendors.aws_access_key == 'aws_access_key').all() 
    assert len(vendors) == 1 
    assert vendors[0].name == 'Name' 

和我的设置LOGIN_DISABLED = True

我的问题是,运行测试current_user从未设置。

我试过登录使用测试客户端,并在with TestLogin.client:包装我的测试,但current_user只是从未设置。有关如何设置它的任何想法?

+0

你叫'login_user'('flask_security固定回报值user_id得到实际的用户。 utils')在你的setUp中?你也可以试试'with self.client:' –

+0

是的,这些工作都没有。 – ruipacheco

+0

如何'self.client.post(...)'而不是'TestViews.client.post(...)' –

回答

6

考虑我这个问题

from flask import Flask, request, 
from flask_login import LoginManager 
from flask_login.utils import login_required, current_user, login_user 

app = Flask(__name__) 
app.secret_key = 'super secret key' 
app.config['SESSION_TYPE'] = 'filesystem' 

login_manager = LoginManager() 
login_manager.init_app(app) 

class MyUser(): 
    name = "tarun" 

    def is_authenticated(self): 
     return True 

    def is_active(self): 
     return True 

    def is_anonymous(self): 
     return False 

    def get_id(self): 
     return 10 


@login_manager.user_loader 
def load_user(user_id): 
    return MyUser() 

@app.route("/login", methods=["POST"]) 
def login(): 
    login_user(MyUser()) 
    return "Authenticated" 

@app.route("/", methods=["GET", "POST"]) 
@login_required 
def index(): 
    return "Authenticated " # + current_user 


if __name__ == "__main__": 
    app.run(debug=True) 

有不同的方法来检测记录在流动创造了下面的示例应用程序。

禁用登录和@login_required

在此,你不要在请求调用使用current_user,只是保障流动到身份验证的用户。在这种情况下,你可以使用下面样的方式

import flasktest as flaskr 

class FlaskrTestCase(unittest.TestCase): 

    def setUp(self): 
     flaskr.app.testing = True 
     flaskr.app.config['LOGIN_DISABLED'] = True 
     flaskr.app.login_manager.init_app(flaskr.app) 
     self.app = flaskr.app.test_client() 

    def test_without_login(self): 
     res = self.app.post("/") 

     assert "Unauthorized" in res.data 

测试将在这种情况下失败,因为用户将能够访问认证流程。 current_user将被设置为匿名用户。它和禁用@login_required一样好。

测试与实际登录

要做到这一点,你需要确保你可以登录到使用POST到端点的应用程序,你实际的登录

import unittest 

import flasktest as flaskr 

class FlaskrTestCase(unittest.TestCase): 

    def setUp(self): 
     flaskr.app.testing = True 
     self.app = flaskr.app.test_client() 

    def tearDown(self): 
     pass 

    def test_login(self): 
     self.app.post("/login") 

     res = self.app.get("/") 

     assert "Authenticated" in res.data 

    def test_without_login(self): 
     res = self.app.post("/") 

     assert "Unauthorized" in res.data 

这甚至将设置current_user正确。在我来说,我没有采取任何形式的数据参数,你的情况,你会使用类似下面

self.app.post('/login', data=dict(
     username=username, 
     password=password 
    ), follow_redirects=True) 

使用会话Cookie

在这种情况下,你设置会话user_id_fresh

def test_login_session(self): 
    with self.app.session_transaction() as sess: 
     sess['user_id'] = '12' 
     sess['_fresh'] = True # https://flask-login.readthedocs.org/en/latest/#fresh-logins 

    res = self.app.get("/") 

    assert "Authenticated" in res.data 

这将依次调用

@login_manager.user_loader 
def load_user(user_id): 
    return MyUser() 

基于由我们会议提供了12

+0

不知道这代表我的问题。 – ruipacheco

+0

@ruipacheco我认为这个答案解决了你的问题,你能解释一下为什么这不能解决你的问题。 – timakro

+0

我试过他显示的所有东西,当我运行单元测试时,在我的视图中仍然没有current_user。不依赖于current_user的视图正常工作。 – ruipacheco

-1

简单的模拟flask_login.current_user并设置像“testuser的”