8

Pythonでのプライベートメソッドのテストについて読んだ後、特にこの受け入れられた答えを参照すると、パブリックインターフェイスをテストするのが最善のようです。ただし、私のクラスは次のようになります。

class MyClass:

  def __init__(self):
    # init code

  def run(self):
    self.__A()
    self.__B()
    self.__C()
    self.__D()

  def __A(self):
    # code for __A

  def __B(self):
    # code for __B

  def __C(self):
    # code for __C

  def __D(self):
    # code for __D

基本的に、関数のパイプラインを介していくつかの入力データを処理するクラスを作成しました。この場合、パブリック関数として公開せずに、各プライベート関数を順番にテストすると便利です。ユニットテストでプライベート関数を実行できない場合、これをどのように処理しますか?

4

4 に答える 4

32

Python は、実際に実行されたコードをまとめるときに、いくつかの名前マングリングを行います。したがって、 にプライベート メソッドがある場合は__AMyClass単体テストで次のように実行する必要があります。

from unittest import TestCase

class TestMyClass(TestCase):
    def test_private(self):
        expected = 'myexpectedresult'
        m = MyClass()
        actual = m._MyClass__A
        self.assertEqual(expected, actual)

質問は、単一のアンダースコアで区切られた、いわゆる「保護された」値に関するものでした。これらのメソッド名はマングルされておらず、簡単に表示できます。

from unittest import TestCase

class A:

    def __a(self):
        return "myexpectedresult"

    def _b(self):
        return "a different result"


class TestMyClass(TestCase):

    def test_private(self):
        expected = "myexpectedresult"
        m = A()
        actual = m._A__a()
        self.assertEqual(expected, actual)

    def test_protected(self):
        expected = "a different result"
        m = A()
        actual = m._b()
        self.assertEqual(expected, actual)
        # actual = m._A__b() # Fails
        # actual = m._A_b()  # Fails
于 2018-05-03T22:15:03.710 に答える
15

まず第一に、あなたは「プライベート」なものにアクセスすることができますね?(または私はここで何かが欠けていますか?)

>>> class MyClass(object):
...     def __init__(self):
...             pass
...     def __A(self):
...             print('Method __A()')
... 
>>> a=MyClass()
>>> a
<__main__.MyClass object at 0x101d56b50>
>>> a._MyClass__A()
Method __A()

MyClassただし、内部のものをテストする必要がある場合は、いつでもテスト関数を記述できます。

class MyClass(object):
    ...
    def _method_for_unit_testing(self):
        self.__A()
        assert <something>
        self.__B()
        assert <something>
        ....

確かに、これを行うための最も洗練された方法ではありませんが、クラスの最下部にあるのはほんの数行のコードです。

于 2013-03-16T19:28:27.600 に答える
0

おそらく、メソッドをテストするだけでよいでしょうrun()__A()ほとんどのクラスには内部メソッドがあります。この場合、 、__B()__C,()およびのすべてのコード__D()が実際に含まれているかどうかは問題ではありrun()ません。問題が疑われる場合、または問題が見つかった場合は、デバッガーの側面に切り替えて、プライベート メソッドをテストすることをお勧めします。

于 2013-03-16T19:03:03.707 に答える