0

我有一组共享一些基本检查的操作。我的代码如下所示:

def is_valid(param): …some pretty complex things unit-tested on their own…

class BaseAction(object):
    def run(self, param):
        if not is_valid(param):
            raise ValueError(…)

        return self.do_run(param)

class Jump(BaseAction):
    def do_run(self, param): …

class Sing(BaseAction):
    def do_run(self, param): …

我应该如何对 BaseAction.run 执行验证的事实进行单元测试?

我想我可以对 Jump.run 和 Sing.run 进行单元测试,但是要正确地做到这一点,我需要为 BaseAction 的每个子类编写测试,可能有很多情况。这也意味着对子类的耦合测试与基类方法的测试。

4

2 回答 2

2

您将对is_valid()函数本身进行单元测试。然后,您只需测试在传递无效输入时.run()引发ValueError异常的事实:

with self.assertRaises(ValueError):
    objectundertest.run(invalid_parameter)

由于您已经有is_valid()自己的单元测试,因此您的单元测试.run()不需要关注它的功能。您可以专注于.run().

在您的情况下BaseAction,是为子类提供服务的单位;我将其作为模拟子类进行测试:

class MockAction(BaseAction):
    run_called = None

    def do_run(self, param):
        self.run_called = param

因此您可以检查是否run确实do_run以预期param值调用。

于 2012-11-07T17:20:48.147 回答
1

如果您想将逻辑保留在您的 Base 类中,请参阅 Martijn Pieters 的回答。

但是,一种可能性是重组您的代码以使验证发生在不是基类的一部分的函数/类中。也许实际运行动作的类本身可以检查那些......

class Jump(object):
    def run(self, param):
        ...

def run_action(action, param):
    if not is_valid(param):
        raise ValueError(…)

    return action.run(param)

单元测试操作更容易(您无需担心基本逻辑),并且如果“BaseAction”以某种方式被破坏,它也不会破坏所有“Jump”单元测试。“run_action”(如果你愿意,你可以把它变成一个类而不是一个函数)本身可以很容易地测试(你可以创建一个假的“Action”对象)。

于 2012-11-07T17:37:01.870 回答