如何用龙卷风测试aioredis

时间:2019-01-09 13:19:35

标签: python testing redis tornado

我正在使用Tornadoaioredis。我想测试aioredis类中我的set实例的一些get调用(aioredis.create_redis_pooltornado.testing.AsyncHTTPTestCase等)。

我试图通过Internet进行访问,但是我还没有找到该怎么做的方法。

在我的aioredis测试中,有没有一种方法可以模拟Redis对临时Tornado数据库的调用。

预先感谢

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,增加了在Application实例之前创建我的Redis连接池的麻烦,以便可以在请求之间共享它。我成功使用了testig.redis,它在一个临时目录中创建了一个Redis实例。该图书馆很旧,多年来没有发生太多事情,但是似乎可以正常工作。无论如何,测试看起来像这样:

import functools

import aioredis
import testing.redis
import redis
from tornado.testing import AsyncHTTPTestCase
from tornado.web import Application

from myapp.base import MyApplication


class TestHandler(AsyncHTTPTestCase):

    def setUp(self) -> None:
        self.redis_server = testing.redis.RedisServer()
        self.redis_client = redis.Redis(**self.redis_server.dsn())
        super().setUp()

    def tearDown(self) -> None:
        self.redis_server.stop()

    def get_app(self) -> Application:
        redis_dsn = self.redis_server.dsn()
        redis = self.io_loop.run_sync(functools.partial(
            aioredis.create_redis_pool, f'redis://{redis_dsn["host"]}:{redis_dsn["port"]}/{redis_dsn["db"]}'
        ))
        return MyApplication(redis)

    def test_client_handler_should_return_200(self):
        self.redis_client.set('val', 'a')
        response = self.fetch('/get-some-redis-data/')
        self.assertEqual(response.code, 200)
        self.assertEqual(response.body, 'a')

为了完成,通常的(非测试)应用程序初始化如下所示:

class MyApplication(Application):
    def __init__(self, redis_connection, *args, **kwargs):
        self.redis_connection = redis_connection
        super().__init__(url_patterns, *args, **kwargs)

async def main():
    redis_connection = await aioredis.create_redis_pool(
        f'redis://{options.redis_host}:{options.redis_port}/{options.redis_db}'
    )
    app = MyApplication(redis_connection)
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port, address=options.listen_ips)
    event = tornado.locks.Event()
    await event.wait()


if __name__ == "__main__":
    asyncio.run(main())

答案 1 :(得分:0)

我使用的库mockaioredis在我的情况下效果很好。

要使用它,首先我将aioredis文件中的sys.modules['aioredis'] = mockaioredis<project>/tests/__ini__.py“模拟”。

第二,我扩展了tornado.web.Application并设置了一种初始化Redis池的方法:

class Application(tornado.web.Application):

    async def _conf_redis(self) -> None:
        loop = asyncio.get_event_loop()
        self.redis = await aioredis.create_redis_pool(address='address',
                                                      password='password',
                                                      loop=loop)

然后我按如下所示设置测试类:

import my.web


class TestHandler(AsyncHTTPTestCase):

    @tornado.testing.gen_test
    async def get_app(self):

        app = my.web.Application([...])

        await app._conf_redis()
        self.redis = app.redis

        return app

现在,可以在任何测试中通过使用self.redis._redis.set(...)self.redis._redis.delete(...)self.redis._redis.hsetnx(...)self.redis._redis.flushdb()正常使用Redis。