• ベストアンサー

JUnitでのプライベートメソッドのテストについて

JavaSE6で開発をしております。 eclipse3.6を用いて、JUnit3でテストを行っているのですが、 クラスのプライベートメソッドをテストするにはリフレクション以外の方法はないのでしょうか。 リフレクションを使う方法ですと、テストコードが複雑になりがちで、publicメソッドに比べると、テストするのがしんどいです。 JUnit3に限らない、他のテストフレームワークでも構いませんので、プライベートメソッドをテストする、よい方法はないものでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.1

なんでprivateなメソッドをテストしなくちゃいけないのか という問題があるけど テストはリフレクション必須ね JUnit-addonsを使えば PrivateAcceccorクラスがあるので これを使えばコードがすこしすっきりするわ

hiropon_su
質問者

補足

回答ありがとうございます。 プライベートメソッドをテストしたかったのはriverotterさんの指摘にもある通り、クラスの共通内部処理の動作確認をしたかったからです。 できるだけ、publicメソッドのテストだけで済むように、リファクタリングを検討するとともに、どうしても必要な場合は、PrivateAccessorを試してみようと思います。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.2

そもそも、なぜプライベートメソッドを用意してるのでしょうか? クラスの拡張などを考慮するとprotectedにした方が良いメソッドも結構あると思います。 本末転倒ですが、もしprotectedにできるなら、protectedメソッドに変更するのも一つの手です。。 プライベートメソッドって、クラス内の共通処理として書いていることが多いと思います。言い方を変えれば、全てのプライベートメソッドは他のメソッドの一部として記述されます。 なので(あくまで私の今までの経験からですが)、publicメソッドのテストケースは関連するprivateメソッドをすべて通るように用意します。 もしそうする事で、一つのメソッド(もしくはクラス)のテストケースが膨大な数になるようでしたら、メソッドやクラスが複数の責務を無理やり一つにまとめているような場合もありますので、一度リファクタリングを検討してみた方が良いと思います。 こういったクラスは、製造時に一生懸命頑張って作ってテストしても保守フェーズで問題になることが多いので、可能であれば製造、単体テスト時点で見直すのがベストです。

hiropon_su
質問者

お礼

回答ありがとうございます。 プライベートメソッドをテストしたかったのはご指摘の通り、クラス内の共通処理の動作確認をしたかったからです。 本来は設計の段階で細かく切り分けた方がよいのでしょうが、 設計の経験値が足りず、ひとつのクラスで動くものを作ってからリファクタリングで切り分ければようとしていました。 そのため、プライベートメソッドが増えてしまい、publicメソッドのテストだけでは、原因がわかりにくくなっていたので、プライベートメソッドのテストケースを書くようになっていました。 回答のおかげで、そもそもプライベートメソッドをテストしなければならない状況がよろしくないことがわかりました。 リファクタリングで、機能の切り分けを検討したいと思います。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • JUnitのテストメソッドごとのメモリの確保とかの話

    JUnit関連の少しコアな話になります。 JUnitではデフォルトでは、実行する際初期処理としてまずテストクラス内のテストメソッドの数だけテストクラスをインスタンス化し、その後各テストメソッドを実行していく、という仕様になっているようです。そしてかつ、各インスタンスはテストクラス内のすべてのテストメソッドが終了するまでインスタンスの破棄は行わないようです。 上記の仕様であるはずだと言う根拠は、テストクラスにコンストラクタを作成し、そこにsysoutを記述することにより確認をしました。 上記の仕様であることが主原因で、Out of Memoryが発生してしまいます。 他にそうなってしまう原因はいくつかあって ・Springを利用していて初期化にメモリを結構使う ・テスト対象のクラスが複雑でテストメソッドの数が多くなる ・パソコンの物理メモリに限界がある ・DJUnitでカバレッジを調査することもあり、またテスティングペアの名前は統一したいので、テスト対象クラスとテストクラスを1対1に対応させたい。 などが挙げられます。VMの実行メモリを大きくしたり、テストクラスを分割してしまうなどの対処療法を行ってきましたが、何とか主原因をつぶす方法は無いものかと質問をした次第です。 (その他、使用しなくなったオブジェクトにnullをセットしたり明示的にgcの実行を指示する等の苦肉の策を行いましたが、ほとんど影響しませんでした) 前置きが長くなりましたが質問は、JUnitでテストを行う際、テストクラス内のテストメソッドの数だけインスタンス化しているものを、あるテストメソッドを実行する直前にインスタンス化し、そのテストメソッドが終了したらそのインスタンスを破棄するような設定はないのか、あればその方法を教えてほしい、ということになします。 だいぶ分かりにくい説明かもしれませんが…。 以上よろしくお願いします。

    • ベストアンサー
    • Java
  • Junit Testの時privateで宣言したメソッドのテスト方法

    お疲れ様です。 junitテストクラスの作成する時 まずテスト対象のクラスをobject生成しますが、 privateで宣言してるメソッドはobject生成後も呼べないから どうやってテスト出来るか分かりません。。。。

    • ベストアンサー
    • Java
  • 抽象クラスをJUNITでテストする方法

    抽象クラス内に実装メソッドと抽象メソッドがある場合に、 そのクラスをJUNITでテストしたいと思っています。 通常のクラスであれば、そのクラスに対するテストクラスを 作成して、テストクラス内でテスト対象クラスをnewして テストケースを記述していくと思いますが、 上記のような抽象クラスの場合は、 どういった形でテストクラスを作成すれば良いのでしょうか? 抽象クラスはnewできないので、 抽象クラスを実装したクラスをまず作成して そのクラスに対するテストクラスを作成するのでしょうか? お薦めの方法や一般的な方法があれば教えてください。 以上、よろしくお願い致しますm(__)m 【環境】 JDK1.4.2 JUNIT3.8.1

    • ベストアンサー
    • Java
  • JUnitのテスト結果の取得方法

    昨日でプロジェクトも一段落つき、現在eclipse + JUnitプラグインでテストする勉強をしています(遊んでる!?) そこで、テストをする材料として今回プロジェクトで作成されている共通クラスを使用していました。 で、全角英数記号文字を半角英数記号文字に変換するメソッドがありテストを書こうとして考えてしまいました。 ”→"と返ってくるはずなのですが、 aasertEquals(""",戻り値)と記述出来ませんよね? このような場合、どうすればいいのでしょうか? まあ、JUnitだけにかかわる問題でもないでしょうし、一般的な事なのかもしれませんがご指導ください。

  • Junitテストでvoid戻り値メッソドをテストする方法

    お疲れ様です。 Junitテストでvoid戻り値メッソドをテストする方法について質問が あります。 戻り値なしのvoidメソッドをassertで検査したい場合どうしたら いいでしょうか。 ただexceptionとかが無く動いたら良いだけです。 お答えお願いします。

    • ベストアンサー
    • Java
  • JAR内のクラス一覧と、メソッド一覧の取得方法

    業務システム(の作成のためのフレームワーク)を解析することになりました。 ソースコードが手に入るものと、クラスファイルしかないクラスがあります。 JudeをつかってUMLのクラス図にしてみたら、クラス数が多いため文字が小さく読みづらく なってしまいました。各クラスのメソッド一覧とシグネチャがわかればいいので、 クラス図ではなく一覧をテキストで出力するツールを作ろうと思っています。 すると.class や .jarを読む必要があるのですが、J2SE1.4のどのクラスを使うと できるでしょうか。リフレクション?と思ったのですが、ツールの実行時に読み込まれる.class や .jarではないので リフレクションでは無理でしょうか? ヒントだけでもいいのでお願いします。

    • ベストアンサー
    • Java
  • テストメソッド

    テストメソッドを使いプログラムを実行させたいのですが、テストメソッドにエラーが出て正常にプログラムが動くかどうか調べられません。 問題は、配列0の数字を、int型のnumShiftsで与えられた数字の回数だけ一番後ろへ移動させ、それ以外の配列の数字を左へシフトさせます。 つまり、一度配列0の中身を一番後ろに持っていくと、配列1の数字が配列0にくるので、それをまた一番後ろにもって行きます。 そしたら配列2の数字が配列0に来ます。それをまた一番後ろにもって行きます。それをnumShifts回繰り返します。 例) ({1,2,3,4,5,6,7}, 3) 3回移動→ {4,5,6,7,1,2,3} ({1,2,3,4,5,6,7}, 0) 0回移動→ {1,2,3,4,5,6,7} ({1,2,3}, 5) 5回移動→ {3,1,2} プログラムは以下のように組みました。 public class ArrayFun { public void shiftNTimes(int[] array, int numShifts) { for (int i = 0; i < numShifts; i++) { //numShifts回繰り返す for (int j = 0; j < array.length-1; j++) { //配列をシフト int temp = array[j+1]; array[j+1] = array[j]; array[j] = temp; } } } } テストメソッドは以下です。 import static org.junit.Assert.*; import org.junit.Test; public class ArrayFunTest { @Test public void testshiftNTimes() { ArrayFun af = new ArrayFun(); int[] a1 = { 1, 2, 3, 4, 5, 6, 7 };//元の配列 int[] a2 = { 1, 2, 3, 4, 5, 6, 7 };//元の配列 int[] a3 = { 1, 2, 3 };//元の配列 int[] a4 = { 4, 5, 6, 7, 1, 2, 3 };//シフト後の配列 int[] a5 = { 1, 2, 3, 4, 5, 6, 7 };//シフト後の配列 int[] a6 = { 3, 1, 2 };//シフト後の配列 assertEquals(a4, af.shiftNTimes(a1, 3)); assertEquals(a5, af.shiftNTimes(a2, 0)); assertEquals(a6, af.shiftNTimes(a3, 5)); } } エラーは、assertEqualsに赤線が出てしまうことです。 このタイプのAssertでのassertEquals(Object, Object)は、(int[], void)に適切ではないと表示されます。 他のテストメソッドではこのようなエラーは出ないのですが・・・。どなたか解決方法をご存知であれば宜しくお願いします。

    • ベストアンサー
    • Java
  • JUnit4での日付の大小比較について

    JUnit4での日付の大小比較について /* 環境 */ JDK 6.0 Update17 eclipse 3.5 JUnit4.7 初めてJUnit4を使ってテストコードを書いてみようと思ったのですが、 日付の大小比較についての記述がわかりません。 例えば、次のコードでyourBirthdayがmyBirthdayよりも後の日付である(大きい)ことを確認するには どのように書いたらよいのでしょうか? import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; ... ... Date myBirthday = ... Date yourBirthday = ... assertThat(myBirthday, is(notNullValue()); assertThat(yourBirthday, is(notNullValue()); // yourBirthday > myBirthday であることを確認したい assertThat(yourBirthday, /* ??? */); ご教示よろしくお願いします。

    • ベストアンサー
    • Java
  • 単体テストの方法教えてください

    質問内容が非常に抽象的で恐縮なのですが、、、 今回Eclipseを使いJSP/Servletでクラスをいくつか作ります。 作成後、具体的にどういった中身のテストクラスを作っていいか分からず困っています。動きをチェックするということは分かってますが実際作ろうとするとどうしてよいか分からなくなります。 イメージでもよいのでご教示お願いします。 (EclipseのJUnitを使えばいいのかなとも思いました)

    • ベストアンサー
    • Java
  • privateのメソッドをリフレクションで呼び出す方法

    privateのメソッドをリフレクションで呼び出す方法 private のメソッドをリフレクションで呼び出す方法 privateのメソッドもリフレクションというもので呼び出せると聞きましたが、やり方がよく分かりません。 aaaやbbbクラスのインスタンスを生成したいのですが、privateやpackage privateのため、そのままだとインスタンスが生成できません。 forNameメソッドやnewInstanceメソッドでどうにかできないかと試してみたのですが、イリーガル例外が発生してしまいます。 何かよい方法がないでしょうか? aaa, bbbのクラスを継承してモックを作成する方法もあるのですが、今回はそういった方法ではなく、privateやpackage privateメソッド(特にコンストラクタ)を外部から呼び出す方法がよいです。 public aaa { private aaa() { } private func() { } } public bbb { aaa() { } private func() { } }

    • ベストアンサー
    • Java