使用unittest测试烧瓶舞蹈

时间:2018-07-24 22:58:20

标签: python flask oauth python-unittest

我已经编写了一个Flask应用程序,该应用程序使用Flask Dance进行用户身份验证。现在,我要测试一些启用了@login_required的视图。

我想进行烧瓶舞蹈测试docs,但无法正常工作。因为我只使用unittest而不是pytest。我也使用github,而不是docs中的google。 sess['github_oauth_token']正确吗?原型样本测试可能如下所示:

def test_sample(self):
    with self.client as client:
        with client.session_transaction() as sess:
            sess['github_oauth_token'] = {
                'access_token': 'fake access token',
                'id_token': 'fake id token',
                'token_type': 'Bearer',
                'expires_in': '3600',
                'expires_at': self.time + 3600
            }

        response = client.post(url_for('core.get_sample'), data=self.fake_sample)

        self.assertRedirects(response, url_for('core.get_sample'))

assertRedirect失败,因为我被重定向到登录页面http://localhost/login/github?next=%2Fsample%2F而不是url_for('core.get_sample')

然后尝试通过遵循烧瓶官方登录名docs来简单地禁用它。

  

在单位时全局关闭身份验证会很方便   测试。要启用此功能,如果应用程序配置变量   LOGIN_DISABLED设置为True,该装饰器将被忽略。

但这还不能正常工作,因为仍然以某种方式执行了login_required,所以测试仍然失败。

所以我的问题是:

  • 因为我使用的是github,而不是google,因为文档中的github_oauth_token是会话的正确密钥?
  • 在使用Flask Dance时,如何使用unittest测试具有@login_required装饰器的视图?

编辑:只要我在用于LOGIN_DISABLED=True的配置类中定义app.config.from_object(config['testing']),它就可以工作,而没有用的是在我的设置方法中设置self.app.config['LOGIN_DISABLED'] = True

1 个答案:

答案 0 :(得分:0)

即使您使用unittest框架而不是pytest进行测试,您仍然可以使用the Flask-Dance testing documentation中记录的模拟存储类。您只需要使用其他机制来用模拟代替实际存储,而不是Pytest的monkeypatch固定装置。您可以轻松地使用unittest.mock软件包,如下所示:

import unittest
from unittest.mock import patch
from flask_dance.consumer.storage import MemoryStorage
from my_app import create_app

class TestApp(unittest.TestCase):
    def setUp(self):
        self.app = create_app()
        self.client = self.app.test_client()

    def test_sample(self):
        github_bp = self.app.blueprints["github"]
        storage = MemoryStorage({"access_token": "fake-token"})
        with patch.object(github_bp, "storage", storage):
            with self.client as client:
                response = client.post(url_for('core.get_sample'), data=self.fake_sample)

        self.assertRedirects(response, url_for('core.get_sample'))

此示例使用application factory pattern,但如果需要,您也可以从其他位置导入app对象。