在应用程序的其他地方调用DI进行单元测试?

时间:2016-04-25 18:43:17

标签: python python-2.7 unit-testing

我正在尝试做类似以下的事情:

import unittest

class foo:
    one = 1
    two = 1

class bar:
    one = 2
    two = 2


class my_test(unittest.TestCase):

    def __init__(self, di_source):
        self.di = di_source
        print 'initing my_test'

    def setUp(self):
        print 'setting up!'

    def tearDown(self):
        print 'tearing down :('

    def test_case_one(self):
        self.assertEqual(self.di.one,1)

    def test_case_two(self):
        self.assertEqual(self.di.two, 2)


di_one = foo()
di_two = bar()

# called from elsewhere in my application
test_one = my_test(di_one).run()
test_one = my_test(di_two).run()

我的目标是:

  • 能够在测试套件上致电run()
  • 在运行时为该测试套件提供DI容器
  • 利用单元测试框架提供的setUptearDown功能

但是,当我尝试这样做时,单元测试框架似乎不喜欢我的构造函数:

AttributeError: 'my_test' object has no attribute '_testMethodName'

是否有更好的方法来构建此示例以避免此问题?

1 个答案:

答案 0 :(得分:1)

如何使用这样的东西:

这允许您为单个套件创建共享资源,将资源传递给所有单元测试,然后使用多种方法测试对象。<​​/ p>

'''Example using a shared resource in a unittest'''


import unittest


def callable_function():
    '''Generic callable_function, this should actually be connected to an object constructor or something else''

    return {'a': 3}


class MyTest(unittest.TestCase):
    '''Custom unittest test case'''

    def __init__(self, resource, method_name):
        super(MyTest, self).__init__(method_name)

        self._resource = resource

    def test_getitem(self):
        '''Test getting item'''

        self.assertEquals(self._resource['a'], 3)

    def test_setitem(self):
        '''Test getting item'''

        self._resource['b'] = 2
        self.assertEquals(self._resource['b'], 2)

    def test_mutable(self):
        '''Test changes persist across tests'''

        self.assertEquals(self._resource['b'], 2)


def run_suite():
    '''Run complete unittest suite'''

    suite = unittest.TestSuite()
    item = callable_function()

    suite.addTests([
        MyTest(item, 'test_getitem'),
        MyTest(item, 'test_setitem'),
        MyTest(item, 'test_mutable'),
    ])

    runner = unittest.TextTestRunner()
    runner.run(suite)


if __name__ == '__main__':
    run_suite()

编辑:如果您需要动态发现方法,可以执行以下操作:

import inspect

def get_tests(cls):
    return [k for k, v in cls.__dict__.items() if k.startswith('test') and inspect.ismethod(v)]

for name in get_tests(MyTest):
    suite.addTest(MyTest(resource, name))

这个想法很简单:覆盖__init__方法,以便获取资源和方法名称,将资源绑定到类,并正常初始化TestCase

运行测试时,只需使用绑定资源。