繁体   English   中英

如何使用自己的方法扩展外部库中的类?

[英]How to augment a class from an external library with own methods?

我有一些特殊情况需要在Django中进行测试。 我正在尝试通过编写自己的测试用例来扩展现有的django测试。 这是我目前的做法。

from django.tests import TestCase

# define my own method as a function
def assertOptionsEqual(self, first, second):
    # logic here
    pass

# Attach the method to the TestCase class. This feels inelegant!
TestCase.assertOptionsEqual = assertOptionsEqual

# tests go here
class KnownGoodInputs(TestCase):
    def test_good_options(self):
        self.assertOptionsEqual(...)

尽管这可行,但将方法定义为以self为第一个参数的函数,然后将其附加到TestCase感觉很不雅致。 有没有更好的方法来用我自己的方法TestCase类? 我可以做这个 ...

class MyTestCase(TestCase):
    def assertOptionsEqual(self, first, second):
        ...

并使用MyTestCase进行所有测试,但想知道是否有更好的选择。 谢谢!

我认为您已经涵盖了这两种选择。 您可以是子类,也可以是Monkeypatch。 通常,猴子补丁程序在运行时实际上不希望更改第三方类,但对此却一无所获,但是取决于您需要进行的更改,这可能是解决错误或确保每次使用该类时都有新方法的唯一方法。 。

因为只有使用您的方法测试才是测试,所以没有必要进行Monkeypatching调试,并且将TestCase子类化是相当合理的。 通常,当您需要扩展现有类的方法时,会使用Monkeypatching。 例如,如果您希望在现有测试用例中对TestCase.assertEqual调用增加逻辑以与Option对象进行比较,则可以通过以下操作对TestCase.assertEqual进行猴子修补,以包括自定义逻辑及其常规逻辑:

originalAssertEqual = TestCase.assertEqual
def newAssertEqual(self, first, second):
    result = originalAssertEqual(first, second)
    if isinstance(first, Option) and isinstance(second, Option):
        # do your custom comparison
    return result
TestCase.assertEqual = newAssertEqual 

但是,似乎至少在此示例中,既不需要子类又不需要猴子补丁。

假定问题在于即使Option实例相等,调用self.assertEqual(firstOptions, secondOptions)也会失败self.assertEqual(firstOptions, secondOptions)您无需编写新的assertOptionsEqual方法。 您可能只需要Option对象来正确定义__eq__

因此,假设您已经:

class KnownGoodInputs(TestCase):
    def test_good_options(self):
        first, second = systemUnderTestGetOptions(...)
        self.assertOptionsEqual(first, second)

上面的firstsecond类是什么?

对于所有Python内置类型, assertEqual应该起作用。 对于自定义Option类,只需执行以下操作:

class Option(object):def init (self):use_foo = False use_bar = True

def __eq__(self, other):
    if (self.use_foo == other.use_foo and
        self.use_bar == other.use_bar):
        return True
    return False

然后假设firstsecondOption实例,则可以像下面这样编写测试:

class KnownGoodInputs(TestCase):
    def test_good_options(self):
        first, second = systemUnderTestGetOptions(...)
        self.assertEqual(first, second)

暂无
暂无

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

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