Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PowerMock/MockitoでCoolに テストコードを書いた話

Avatar for Pakkun Pakkun
December 25, 2019

PowerMock/MockitoでCoolに テストコードを書いた話

JJTC第一回 発表資料

Avatar for Pakkun

Pakkun

December 25, 2019
Tweet

More Decks by Pakkun

Other Decks in Programming

Transcript

  1. 自己紹介 何故テスト コードを書くのか? 02 INTRODUCTION Why we do Testing? 01

    パワーモック/モックについ て PowerMock/Mockito 04 Why Should We Use Mockito? なんでモキットなの? 03
  2. public int sum(int a, int b) { return a +

    b; } <テスト対象> ...? テストしまーす Hoge.java
  3. public void deleteLine(String word) { Line line = repository.findWord(word); //

    引数で渡された単語を含む行を探す repository.delete(line); // 対象の行を削除する } <テスト対象> Q. 上記テスト対象のメソッドの「単体テスト」を作成する場合、  stubに置き換えた方が良いものは? 1. Line 2. word 3. repository 質問 LineManager.java stub:テスト用に用意した、本来の部品の代わりのもの
  4. public void deleteLine(String word) { Line line = repository.findWord(word); //

    引数で渡された単語を含む行を探す repository.delete(line); // 対象の行を削除する } <テスト対象> Q. 上記テスト対象のメソッドの「単体テスト」を作成する場合、  stubに置き換えた方が良いものは? 1. Line 2. word 3. repository 答え 僕には時間がないんだ!「 repository」は他でテストしてくれ! deleteLineのメソッド単体の挙動をテストすることが大事! LineManager.java
  5. public void deleteLine(String word) { Line line = repository.findWord(word); //

    引数で渡された単語を含む行を探す repository.delete(line); // 対象の行を削除する } <テスト対象> じゃあどうやってStubにすんの <テストコード(一部)> Line line = new Line(); // 適当な行をnewして repositoryStub.setLineToFind(line); // 作ったスタブの戻り値をセット lineManager.setRepository(repositoryStub); // repositoryをStubに置き換える lineManager.deleteLine("hoge"); // テスト対象のコードを実行 repositoryStub.verifyLineDeleted(line); // テスト対象のコードが「行削除」のコードを呼び出しているか 確認する 自分で「 RepositoryStub」を作るしかないよね。。。 (作ったとして) LineManager.java LineManagerTest.java
  6. Mockito を選んだ理由 https://trends.google.co.jp/trends/? geo=JP 1. 良く使われてるじゃん #ググりやすそう(大事) 2. 他のライブラリと比べ  コード量が少ないじゃん

    #時間がない! 3. Stub-Run-Assert #考え方が自分と良く会う # 「Mocks aren't Stubs」- Martin Fowler 氏  に沿っており、TDDの思考と逆行しない。  ThoughtWorks社の開発者もMockito使ってるらしい。  (TDDについてはまた次回 )
  7. Mockito/PowerMockのモックオブジェクトの種類 ① mockメソッドのモックオブジェクト - 基本的にモックの全メソッドが無効となる - テストに都合の良い値を返すようにメソッド定義を上書きする必要がある ② spyメソッドのモックオブジェクト -

    元の処理が実行される - 挙動を変更したいメソッドに対して、定義を上書きする必要がある 一部は元通りの処理、一部は挙動を変更したい場合にspyを使う それ以外全て普通のmockメソッドを利用しましょう。
  8. 実装方法(Maven利用) 1. dependencyをpomに追加 <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-easymock</artifactId> <version>----</version> </dependency> <dependency> <groupId>org.powermock</groupId>

    <artifactId>powermock-module-junit4</artifactId> <version>----</version> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-core</artifactId> <version>----</version> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>----</version> </dependency>
  9. 2. モジュールインポート 3. runner指定(テストクラスに下記のアノテーションを設定) ## Mockitoのみの場合 @RunWith(MockitoJUnitRunner.class) public class XxxTest

    {…} ## PowerMockを使う場合 @RunWith(PowerMockRunner.class) @PrepareForTest({Hoge.class, Fuga.class}) // PowerMockが扱うクラス public class XxxTest {…} import static org.mockito.ArgumentMatchers.*; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import org.powermock.modules.junit4.PowerMockRunner; import org.mockito.Mock; import org.mockito.Spy;
  10. 実際に書いてみよう! パターン:private メソッドのモック化が必要な場合 public class Hoge { public void doSomething()

    { ... String key = ...; String value = this.getProperty(key); ... } private String getProperty(String key) { ... return xxx; } } クラス定義
  11. @RunWith(PowerMockRunner.class) @PrepareForTest({Hoge.class}) public class HogeTest { public void testDoSomething() {

    Hoge h = PowerMockito.spy(new Hoge()); PowerMockito.doReturn(“dummy value”).when(h, “getProperty”, anyString()); h.doSomething(); ... assertThat(...); } } テストロジック
  12. Expect-Run-Verify 他の模擬Objのテストフレームワークはどうだったか(Mockito以外) // expect Line line = new Line(); expect(mockRepository.findLine("foo")).andReturn(line);

    mockRepository.delete(line);←検証すべきコード // run replay(mockRepository); lineManager.deleteByWordLists("foo");←テストの実行 // verify verify(mockRepository); EasyMock
  13. EOF