繁体   English   中英

如何使用Twisted Trial对Autobahn应用程序进行单元测试?

[英]How to do unit test on Autobahn applications using Twisted Trial?

假设您只使用Autobahn连接(不是原始WebSocket)。

我们如何在没有网络,RPC方法和事件的情况下进行测试?
由于它是Twisted,我认为最合适的工具是Twisted Trial。

但我无法弄清楚如何编写这些测试,而不需要编写大量的样板代码并重新使用Autobahn的内部实现(甚至我不确定我是否能够这样做)。

你会怎么做?

这是试图回答我自己的问题。

问题

然后,为了对RPC方法和事件进行单元测试,我们需要假设Autobahn经过了充分测试,我们不必测试它,解决方案变得简单:

解决方案

嘲笑所有。

上下文

在我的应用程序中,我有两种类型的组件(读取ApplicationSession):StandardComponent和DatabaseComponent(继承自StandardComponent)。

单元测试中最大的问题是我们有很多依赖项,比如数据库连接,Redis连接等等......

例子

我在测试中做的是通过unittest.TestCase来修补所有这些对象:

class APITestCase(unittest.TestCase):

    def _patchObject(self, module_name, **kwargs):
        patcher = patch(module_name, **kwargs)
        mock = patcher.start()

        self.patches.append(patcher)
        return mock

    def setUp(self):
        logging.disable(logging.CRITICAL)
        self.patches = []
        self.session = self._patchObject('components.ApplicationAPI')
        self.database = self._patchObject('txpostgres.txpostgres.Connection')

    def tearDown(self):
        for patcher in self.patches:
            patcher.stop()

我在我的测试用例中注入了一个模拟会话和一个模拟数据库。

然后,测试变得非常简单。

每当我调用一个需要调用数据库或从数据库中获取结果的RPC方法时,我都会修补它: self.mocked_auth_user.return_value = (1, "abc", "something", "admin")

在我的测试方法中:

def test_authenticate_success(self):
    self.mocked_auth_user.return_value = (1, "abc", "paris", "admin")

    def _doTest(auth_result):
        attempted_auth_result = {
            "secret": "abc",
            "role": "admin",
            "authid": "1",
            "salt": "paris",
            "iterations": 1000,
            "keylen": 32
        }

        self.assertEqual(auth_result, attempted_auth_result)
        self.mocked_auth_user.assert_called_with(self.api.database, "raito")

    return self.api.authenticate("test", "raito", {}).addCallback(_doTest)

您可以执行一些更高级和有趣的测试,以查看您的方法是否是防错的:

def test_authenticate_authid_not_found(self):
    def _raiseException(db, user):
        return defer.fail(Exception("User {} not found!".format(user)))

    self.mocked_auth_user.side_effect = _raiseException
    return self.failUnlessFailure(self.api.authenticate("test", "raito", {}), AuthenticationError)

对于事件也是如此,你只需要调用它们并测试它们是否发布了一个事件( self.session.publish.assert_called_with(...)

它变得神奇!

无论如何,它解决了单元测试问题,但整合还没有。 我正在努力,但问题可能会使用一些虚拟化技术(Docker)或类似的东西来解决。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM