eclipseで小文字を大文字に
小文字を大文字にする
選択して、ctrl + shift + X
大文字を小文字にする
選択して、ctrl + shift + Y
ServletOutputStreamの取得
とあるテストケースで、
ServletOutputStream.writeを使った結果をassertしたくなりました。
ググってもググってもByteArrayOutputStream使えばいいよ!という答えしか出てこなくて
途方に暮れた。。。
が、assertの方法をちょっと変えることで回避。
ResponseWrapper#getResponseBody の結果のbyte[]でassertすることにした。
具体的にはこんな感じで
// 外側のクラスをインスタンス化 final SampleResponseWrapper target = new SampleResponseWrapper(res); // mockのresponseを使って、privateメソッドを呼び、outputStreamを詰め込む。 target.getOutputStream(); ServletOutputStream csrw = (ServletOutputStream) field.get(target); csrw.write(129); // 結果のbyte配列をint型に変える int intValue = 0; for (byte b : target.getResponseBody()) { intValue = b; if (intValue < 0) { intValue += 256; } } assertEquals(129, intValue);
テスト対象のクラスは、ざっくりこんな感じ
public class SampleResponseWrapper extends HttpServletResponseWrapper { /** 出力バッファ */ private InnerClassOutputStream wrappedOut; /** 内部クラス */ private static class InnerClassOutputStream extends ServletOutputStream { /** 内部クラスの出力バッファ */ private ByteArrayOutputStream buffer; @Override public void write(int b) throws IOException { buffer.write(b); } } }
SampleResponseWrapper は、HttpServletResponseWrapperを継承したクラス。
その中のフィールドに「wrappedOut」がいて、
その型はSampleResponseWrapper の内部クラス(private static)。
結局本質的なテストができてない気はムンムンしつつ、
思ったことは、
何でもかんでもprivateにしないで・・・ということ(自分が作ったクラスじゃないので)
いや、必要ならprivateでももちろん構わないけど、
単体テストのカバレッジを見逃すとか、そういう配慮的な何かがほしかった。
テスト設計って、大事だなーって。
カバレッジ100%っていうのは管理上確認するのは簡単だけど、
本当にそのテストが品質を担保してるのか?っていったら微妙だと思う。
(むしろ、カバレッジを上げるのに時間を使ってしまって、
単体テストケースを考えたりレビューしたりする時間が減るのではないかと。)
テストケース(しかも単体)なんて、もっと機械的にできてもいいのになぁ??と
思ってしまう自分でした。
log4jdbc+slf4jでJDBC周りのログを出す
タイトルまま。
log4jだけだとPrepareStatement.addBatch()のログが出ないので、
出せるように修正。
いいなと思ったのは、既存のlog4jの設定には手を加えなくてもいいこと。
(追記は必要。)
必要なライブラリ:
log4jdbc4-1.2.jar
slf4j-api-1.7.7.jar
slf4j-log4j12-1.7.7.jar
(mavenつかってればpom書けばいいんだけどなぁ…)
jdbc設定の修正
今はoracleを使ってるので、jdbcの設定は以下のような感じ。
driver=oracle.jdbc.OracleDriver url=jdbc:oracle:thin:@host:1521/sid
それを、こう。
driver=net.sf.log4jdbc.DriverSpy url=jdbc:log4jdbc:oracle:thin:@host:1521/sid
ドライバ名は、JDBC接続文字列から勝手に判定してくれてるのかな。
とくに設定する必要はありませんでした。
log4j.propertiesに以下を追記
log4j.logger.jdbc.audit=DEBUG, consoleLog log4j.additivity.jdbc.audit=false log4j.logger.jdbc.resultset=DEBUG, consoleLog log4j.additivity.jdbc.resultset=false log4j.logger.jdbc.sqlonly=DEBUG, consoleLog log4j.additivity.jdbc.sqlonly=false log4j.logger.jdbc.sqltiming=DEBUG, consoleLog log4j.additivity.jdbc.sqltiming=false log4j.logger.jdbc.connection=DEBUG, consoleLog log4j.additivity.jdbc.connection=false log4j.logger.log4jdbc.debug=OFF, consoleLog log4j.additivity.log4jdbc.debug=false
出たログを見た感じ、今は[audit]と[sqltiming]があれば十分っぽい。
auditでPrepareStatementのログを出してくれて、
sqltimingで実際に発行するSQLを出してくれる。
なお、アプリケーションログの設定があれば、そちらも変わりなく出力される。
mavenでコンパイルするときのJDKバージョンの指定
mavenつかってコンパイルするときに
JDKのバージョンを明示的に指定したい。
つかうのはmaven-compiler-plugin
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <testSource>${jdk.version}</testSource> <testTarget>${jdk.version}</testTarget> <encoding>${project.build.sourceEncoding}</encoding> <compilerArguments> <verbose /> <!-- <bootclasspath>${env.JAVA_HOME5}\jre\lib\rt.jar</bootclasspath> --> <bootclasspath>C:\Program Files\Java\jdk1.8.0_20\jre\lib\rt.jar</bootclasspath> <!-- -noverify --> </compilerArguments> </configuration> </plugin>
source : 受け付けるソースコードのバージョン
target : ここに指定したバージョン以降で動作することを保証する
compilerVersion:Version of the compiler to use()
いろいろためしてみよう。
①
source:1.6
target;1.8
compilerverrsion:1.8
理想の挙動:java8でコンパイルされて、java8で動く。
java6だと動かない。
②
source:1.6
target:1.6
compilerversion:1.8
理想の挙動:java8でコンパイルされて、java6で動く。
java8でももちろん動く。
試してみたら挙動を追記します。
java8でコンパイルすると java.lang.VerifyError
ふっるいソースをjava8でコンパイル+テストしようとしたところ、
以下のようなエラーが出た。
Expecting a stackmap frame at branch target 43
Exception Details:
Location:
jp/sample/xx/xx/.
Reason:
Expected stackmap frame at this location.
FuRyu Tech Blog » Blog Archive » 既存プロジェクトをJDK8へ移行したら、java.lang.VerifyErrorが出た
↑参考になりそう。
djunitから脱却したいな~。
sql*plusをlinuxにインストール
最近環境構築ばっかりやってるな。。。
・centos6.5に
・sqlplusを
インストール。
インストールといっても、yumとか使わなくても
zipを展開してパスを通せば使えるようになるらしいので、レッツチャレンジ。
1. 資材調達
instantclient-basic-linux.x64-12.1.0.2.0.zip
instantclient-sqlplus-linux.x64-12.1.0.2.0.zip
を取得。
取得もとは
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html
(ユーザ登録が必要)
rpmも配布してるので、zipがダメだったらrpmでインストールしよう。
2. linux上で展開
/usr/local/bin/instantclient-basic-linux.x64-12.1.0.2.0.zip
という構成にして、
cd /usr/local/bin
unzip instantclient-basic-linux.x64-12.1.0.2.0.zip
unzip instantclient-sqlplus-linux.x64-12.1.0.2.0.zip
3. PATH通す
export PATH=$PATH:/usr/local/bin/instantclient_12_1
4. ためしうち
[root@xxxxx instantclient_12_1]# sqlplus
sqlplus: error while loading shared libraries: libsqlplus.so: cannot open shared object file: No such file or directory
「libsqlplus.so」がないってよ
・・・?ん?
instantclient-sqlplus-linux.x64-12.1.0.2.0.zipの中に入ってるけどなあ。
5. 環境変数に「LD_LIBRARY_PATH=/usr/local/bin/instantclient_12_1」を追加する
PATHだけ通せばいいかと思いきや、「LD_LIBRARY_PATH」という環境変数が必要でした。
sqlplusの内部で必要なのかなあ。
6. リベンジ
[root@xxxxx bin]# sqlplus
SQL*Plus: Release 12.1.0.2.0 Production on Thu Oct 30 13:17:00 2014
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Enter user-name:
リベンジ完了!