プライベートメソッドを公開して単体テストを行うのは良い考えでしょうか? 質問する

プライベートメソッドを公開して単体テストを行うのは良い考えでしょうか? 質問する

モデレーター注: ここには既に 39 件の回答が投稿されています (削除されているものもあります)。回答を投稿する前に、議論に何か意味のあることを追加できるかどうかを検討してください。おそらく、他の誰かがすでに述べたことを繰り返しているだけでしょう。


時々、ユニット テストをいくつか記述するためだけに、クラス内のプライベート メソッドをパブリックにする必要があることに気が付きます。

通常、これはメソッドにクラス内の他のメソッド間で共有されるロジックが含まれており、ロジックを単独でテストする方が整理されているためです。または、スレッドの問題を心配せずに同期スレッドで使用されるロジックをテストしたいという別の理由も考えられます。

私があまりやりたくないから、他の人もこれをやっているのでしょうか?? 個人的には、クラス外で実際には何のサービスも提供しないメソッドを公開することによる問題よりも、メリットのほうが大きいと思います...

アップデート

皆さん、回答ありがとうございます。皆さんの興味をそそったようです。テストはパブリック API 経由で行うべきというのが一般的なコンセンサスだと思います。これがクラスが使用される唯一の方法だからです。私もこれに同意します。私が上で述べた、これを実行するいくつかのケースは珍しいケースでしたが、それを実行することのメリットは価値があると思いました。

しかし、そんなことは絶対に起こってはならないという皆さんの意見も理解できます。そして、もう少し考えてみると、テストに対応するためにコードを変更するのは悪い考えだと思います。結局のところ、テストはある意味ではサポート ツールであり、いわゆる「サポート ツールをサポートする」ためにシステムを変更するのは明らかに悪い習慣です。

ベストアンサー1

注:
この回答は元々この質問に対して投稿されたものです単体テストだけが、ゲッターを介してプライベートインスタンス変数を公開する正当な理由になるでしょうか?これはこれに統合されたため、ここで提示されたユースケースに少し特化している可能性があります。

一般的に言えば、私は通常、テストを容易にするために「本番」コードをリファクタリングすることに賛成です。しかし、ここではそれが良い判断ではないと思います。優れた単体テストは (通常) クラスの実装の詳細ではなく、目に見える動作のみを考慮に入れます。内部スタックをテストに公開する代わりに、first()またはを呼び出した後にクラスが期待どおりの順序でページを返すかどうかをテストできますlast()

たとえば、次の疑似コードを考えてみます。

public class NavigationTest {
    private Navigation nav;

    @Before
    public void setUp() {
        // Set up nav so the order is page1->page2->page3 and
        // we've moved back to page2
        nav = ...;
    }

    @Test
    public void testFirst() {
        nav.first();

        assertEquals("page1", nav.getPage());

        nav.next();
        assertEquals("page2", nav.getPage());

        nav.next();
        assertEquals("page3", nav.getPage());
    }

    @Test
    public void testLast() {
        nav.last();

        assertEquals("page3", nav.getPage());

        nav.previous();
        assertEquals("page2", nav.getPage());

        nav.previous();
        assertEquals("page1", nav.getPage());
    }
}

おすすめ記事