Mockitoの実験(モックを用いた単体テスト)
さて、結構サンプルが転がってるわけですが、(公式のドキュメントもしっかりしているし?)
なんとなく古い人間としては、全Mocというよりは、spyがキモになるんじゃないのかなぁ?なんて思ったり。
もっとも、最近のDI全盛においては全mocをDIするといったケースが多々あるのでその限りではございませんが・・・
ひとまず、古い人間にjunitでモックのテストを書け。となるとこんな感じか・・
以下の様なLogicとDaoがあって、daoが未完成で、Logicの計算部分のテストがしたい。
package logic; import dao.SettingsDao; public class CalcLogic { /** * 設定の税率で金額を求め、送料を付与して返す。 * * @param price 金額 * @return 合計金額 */ public int calcPrice(int price) { //インラインでインスタンスを取得しているのでMoc化できない。 //SettingsDao settingsDao = new SettingsDao(); // メソッド化 SettingsDao settingsDao = getInstance(); return (int)Math.floor(price * (1 + settingsDao.getTaxRate())) + settingsDao.getTransportation(); } /** * 設定情報取得Daoを返却する。 * @return */ protected SettingsDao getInstance() { return new SettingsDao(); } }
package dao; public class SettingsDao { /** * DBより税率を取得して返す。 * @return 税率 */ public double getTaxRate() { return 0.5; } /** * DBより送料を取得して返す。 * @return 送料 */ public int getTransportation() { return 500; } }
そんでもって、テストはこんな感じ
package logic; import static org.junit.Assert.*; import org.junit.Test; import dao.SettingsDao; public class CalcLogicTest { @Test public void testCalcPrice() { CalcLogic logic = new CalcLogic() { @Override //DaoのMocを返す。 protected SettingsDao getInstance() { return new SettingsDao() { @Override public double getTaxRate() { return 0.03; } @Override public int getTransportation() { return 200; } }; } }; int calcPrice = logic.calcPrice(200); assertEquals(406, calcPrice); } }
これをMockItoを使ってみるとこんな感じかな?
package logic; import static org.junit.Assert.*; import org.junit.Test; import dao.SettingsDao; import static org.mockito.Mockito.*; public class CalcLogicMockItTest { @Test public void testTestCalcPrice() { CalcLogic logic = spy(new CalcLogic()); SettingsDao dao = spy(new SettingsDao()); when(dao.getTaxRate()).thenReturn(0.03); when(dao.getTransportation()).thenReturn(200); when(logic.getInstance()).thenReturn(dao); int calcPrice = logic.calcPrice(200); assertEquals(406, calcPrice); } //個人的には以下も慣れていてすきですが中途半端ですやね。 @Test public void testTestCalcPrice_個人的には好きなテスト() { CalcLogic logic = spy(new CalcLogic()); when(logic.getInstance()).thenReturn(new SettingsDao() { @Override public double getTaxRate() { return 0.03; } @Override public int getTransportation() { return 200; } }); int calcPrice = logic.calcPrice(200); assertEquals(406, calcPrice); } }
見た目的にはかなりすっきりしたのではないでしょうか。
下のテストは気にしないでください。個人的には好きなだけですので。