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

ロジックを基本クラスに保持したい場合は、Martijn Pieters の回答を参照してください。

ただし、コードを再構築して、基本クラスの一部ではない関数/クラスで検証が行われるようにすることが 1 つの可能性です。実際にアクションを実行するクラス自体がそれらをチェックできるかもしれません...

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 に答える