カプセル化■プライベートメソッドをテストする方法

■ このスレッドは過去ログ倉庫に格納されています
2020/07/05(日) 20:47:46.60ID:M+BkbwUs
■短い回答
プライベートをテストしたい場合は設計に問題があるので、パブリックに変更してテストしましょう

■これに対する(変な人の)驚いた反論

プライベートを一時的にパブリックにして、テストが終わったら
プライベートに戻すなんてやるわけないだろw
↑誰もそんなコトしろなんて言ってない

■テスト専門家による回答

t-wadaのブログ
https://t-wada.hatenablog.jp/entry/should-we-test-private-methods

短くまとめると、プライベートなメソッドのテストを書く必要は 無い と考えています。

ほとんどのプライベートメソッドはパブリックメソッド経由でテストできるからです。
プライベートメソッドは実装の詳細であり、自動テストのターゲットとなる「外部から見た振る舞い」ではありません。
プライベートなメソッドのテストに関しては、4つの考え方があります。

・パブリックメソッド経由でテストする
・別クラスのパブリックメソッドとする
・テスト対象の可視性を(やや)上げる
・プライベートのまま、リフレクションでアクセスしてテストを書く

パブリックメソッド経由でテストする
多くの場合、そのクラスのパブリックメソッド経由でプライベートメソッドのテストも同時に行えます。テストできているか不安があるならテストカバレッジを確認しましょう。

別クラスのパブリックメソッドとする
プライベートなメソッドのテストを書きたいということは、実はテスト対象の責務が多すぎることを示唆している場合があります。
テストがどうしても書きたい場合は、その責務はテスト対象のプライベートな振る舞いではなく、他の誰かのパブリックな振る舞いなのでしょう。
2020/07/05(日) 20:48:27.27ID:M+BkbwUs
前スレ

カプセル化の有害性、オブジェクト指向は愚かな考え
https://mevius.5ch.net/test/read.cgi/tech/1592491656/
2020/07/05(日) 20:51:53.15ID:M+BkbwUs
クソコード例。こんなコード書いてるやつが、privateのテストで
パブリックに変更してテストするのはおかしいとか言ってる(笑)
lenが配列(笑)理由 int型にはnullが入れられないから(笑)

https://mevius.5ch.net/test/read.cgi/tech/1592491656/805
ずれるかもしれないが下のような場合、privateにnullを突っ込んだらヌルポだが
privateをわざわざコード弄ってまで別にテストするようなことは少なくとも
ビジネスソフトでは知ってる限り無い。組み込みとかは知らんし必要ならやれば良いけど。

class ChinTester {
public void testChin(int[] len) {
if (len==null){System.out.println("You are a woman");
return;}
if (len.length<11){ uncS(len);}
else{funcB(len);}
return;}

private void funcS(int[] len){
if (len.length<9){System.out.println("Smallest");
}else{System.out.println("Smaller");}
return;}

private void funcB(int[] len){
if (len.length<14){System.out.println("Medium");}
else if (len.length<16){System.out.println("Bigger");
}else{ System.out.println("Wow!");}
return;}
}
2020/07/05(日) 20:53:33.00ID:M+BkbwUs
983 名前:デフォルトの名無しさん[] 投稿日:2020/07/05(日) 14:18:27.81 ID:9F15TCk0 [68/74]
正直あの短さでOOかどうかと(スタティックでインスタンス化もないコードだが)言うのは
不毛だけどID:JiRnWiGCの組み込みおじさんのがOO感はあるよ。

で、staticで出されてもprivateのテストがどうかと言う話には全く寄与しないわけだが、
じゃあ逆に、>>805のチンコテストのfuncSとfuncBはどうやってテストするの?

パブリック経由で全パターンと言うことならこれでこの話はおしまい。
パブリック経由でやりましょう。

違うと言うなら具体的にコードでおながいします。
2020/07/05(日) 20:54:53.36ID:M+BkbwUs
>>4への回答
設計に問題があるので、コードを修正しましょう。
修正すれば自然とpublicになります↓

926 名前:デフォルトの名無しさん[] 投稿日:2020/07/05(日) 12:20:23.64 ID:MQ9nuMmc [21/53]
>>805
こう書いた方が良いと思うの
https://paiza.io/projects/mPhqBnYZnQukkW6HY9LmOQ
2020/07/05(日) 20:57:49.33ID:M+BkbwUs
>>5の補足、これはまだプライベートですが
普通はMainクラスにコードをごちゃごちゃ書かないので
judgeLengthを含むクラスを作成します。

そしてmainから呼び出します。
必然的にjudgeLengthメソッドはパブリックになります。
7デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:03:41.24ID:MQ9nuMmc
>>6
judgeLengthをpublicにしてよいかどうか、オブジェクトをわけて良いかどうかは微妙なところで
publicにした場合って他のオブジェクトからも参照可能になってしまうので
そこの依存があとあとjudgeLengthの修正をできなくする可能性があるので
privateにするっていうのは他のオブジェクトから依存させないようにして独立させる意味もあるので
テストするためにpublicにしますっていうのは僕はやっぱり反対ですね
8デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:04:50.23ID:MQ9nuMmc
僕が書いたように同じオブジェクトにテストコードも書いちゃえば良いと思います
2020/07/05(日) 21:07:40.54ID:M+BkbwUs
>>7
微妙でもなんでもねーよ
Mainクラスに関係ない処理を入れるな

これは小さいサンプルだが、大きくなった時
Mainクラスに、そんな処理はいってたらおかしいだろ
なんで(大きくなったコードの)その他の部分は別のクラスにあるのに
この処理だけMainクラスにあるんだ?って
10デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:09:37.34ID:MQ9nuMmc
>>9
Mainクラスと関係ある処理だからMainクラスにあるんじゃよ
Mainクラスからしかアクセスしないからprivateなんじゃよ
テストするためにpublicにするのはおかしいのじゃよ
2020/07/05(日) 21:11:26.55ID:M+BkbwUs
>>10
Mainクラスと関係ある処理だから?

じゃあ名前が悪いよね。
誰が「Mainクラス」と聞いて
その中にある処理を想像できるんだ?w
12デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:13:00.77ID:MQ9nuMmc
>>11
えっと、前にも言ったけどpaizaはMainという名前じゃないと動かないんだよ
Mainとわけてクラスを作ることもできるけど面倒だからやらなかっただけ
普通のプログラマならpaizaの制約ぐらい知ってるだろうし説明する必要もないと思ってた
君の無知さを想像できなかった僕のミスだ
13デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:13:24.90ID:MQ9nuMmc
君が無知すぎてごめん
14デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:14:24.05ID:MQ9nuMmc
誠にごめんなさい
2020/07/05(日) 21:14:43.14ID:M+BkbwUs
>>12
だから分けろって。設計がおかしいだろ。

Mainクラスにメインの処理を入れるな
設計が悪いって言ってるのになんで理解できない?
2020/07/05(日) 21:15:37.89ID:M+BkbwUs
プライベートをテストしたいっていうのは
本質的に設計が悪いってことが理解できないやつ
もしくは設計なんてしたことがないやつなんだろう
17デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:15:45.13ID:MQ9nuMmc
>>15
てめえでやれやハゲ
2020/07/05(日) 21:16:23.44ID:M+BkbwUs
>>17
だからやるのが正解だろw
19デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:17:00.58ID:MQ9nuMmc
>>16
君は簡単なロジックしか組む機会がなかった幸せな人だと思うよ
僕は君が羨ましい、幸せな人生を歩んでいるね
20デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:17:17.30ID:MQ9nuMmc
>>18
やってない君が不正解だね
21デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:19:16.27ID:MQ9nuMmc
僕は下痢便コードをこうするべきって修正したよ
paizaで動くようにMainというクラス名に変えたけどね
paizaだからそうなるよねってみんな理解してくれるものと思ってた
paizaを知らない木偶の坊がクラス名に文句つけてきたとき僕は絶望した
2020/07/05(日) 21:20:28.56ID:Xwol7cCi
まだやってたのかw
>>5みたいな下痢便コードが出てきた時点で
「あっ・・・(察し)」でスレ終了でしょ
23デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:21:29.14ID:MQ9nuMmc
こうするべきだと思うならやれば良いがな
自分でやりもせず他人に文句いうだけの人間は木偶の坊のそしりを免れないよ
2020/07/05(日) 21:22:53.14ID:M+BkbwUs
Mainに他のクラスの処理を全て同居させる

全部Mainにあるから呼び出せるよね?と
publicメソッドをprivateメソッドに変更

publicメソッドはMainのみ!
と言い

あぁ、プライベートメソッドのテストができない〜と嘆く(笑)

アホなのか?自分でテストできないようにクソ設計に変更して
自業自得じゃんw
2522
垢版 |
2020/07/05(日) 21:23:27.95ID:Xwol7cCi
×>>5みたいな下痢便コードが出てきた時点で
>>3みたいな下痢便コードが出てきた時点で

すまん訂正
26デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:25:43.01ID:MQ9nuMmc
>>24
君はまだMainという名前のレトリックから抜け出せてないように見える
paizaで動かすためにMainという名前にしたってだけだから
実際にはそれなりの名前になるでしょう
privateメソッドは当然クラスと関係あるものになるでしょうということ

Mainという名前に囚われ過ぎておられるように見受けられる
自分だったらこう書くのにって言うのがあるならそれを実践してみるべきかと思われます
2020/07/05(日) 21:25:44.19ID:M+BkbwUs
おそらく設計とは何かを知らずに、
ただ動けばいいと思ってるんだろう

テストしやすく設計するのも
設計の一つ
28デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:26:22.28ID:MQ9nuMmc
>>27
Mainを勘違いしてたアホが何抜かしとんねん
2020/07/05(日) 21:26:36.76ID:M+BkbwUs
>>26
だからテストしやすようにjudgeLengthメソッドを含んだ
クラスを作るだけ
2020/07/05(日) 21:27:04.67ID:M+BkbwUs
>>28
勘違いしてませんが?
Main関数とロジックを同居させるなの意味がわかりませんか?
31デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:27:05.17ID:MQ9nuMmc
謙虚になれや
オブジェクト指向とは礼儀作法と心得よ
32デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:27:44.35ID:MQ9nuMmc
>>30
はいはいもうえーから
2020/07/05(日) 21:27:45.52ID:Xwol7cCi
>>27
Mainクラス云々については単に誤解してると思うけど
このスレの登場人物じゃあ多分おまいが一番マシな感性持ってそうやなw
34デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:28:41.91ID:MQ9nuMmc
>>29
作ってへんやんけ
35デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:28:59.67ID:MQ9nuMmc
やりもせずに何抜かしとんねん
36デフォルトの名無しさん
垢版 |
2020/07/05(日) 21:29:55.13ID:MQ9nuMmc
ほんま口だけやな
2020/07/05(日) 22:31:17.31ID:cdjjBT1g
あら。続いていたのか。
2020/07/05(日) 22:53:15.98ID:VS9zJ3bZ
このスレの主旨的にはprivateメソッドのテストコードを書きたいんだよね?
書く必要がないって主張は違うよね?
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況