Spring Boot 2.7を利用したJavaアプリケーションでPowerMockを利用する際、mockito-coreやpowermockで特定のバージョンを指定することで、JUnit4とJUnit5に加え、PowerMockも利用可能となる。
今回は、Spring Boot 2.7を利用したJavaアプリケーションのJUnitによるテストコードで、PowerMockを利用してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
また、PowerMockを利用したテストコードの参照元は、下記記事とする。
サンプルプログラムの作成
作成したサンプルプログラムの構成は、以下の通り。なお、下記の赤枠については、後述する。
pom.xmlの内容は以下の通りで、JUnit4, JUnit5に加え、PowerMockも利用できるよう、変更している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example.demo</groupId> <artifactId>demoSpringTest</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>demoSpringTest</name> <description>Demo Web Project for Spring Boot on Azure</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!-- バリデーションチェックを行うための設定 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <!-- lombokを利用するための設定 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <!-- SQL Serverを利用するための設定 --> <!-- ドライバーが SSL (Secure Sockets Layer) 暗号化による SQL Server への安全な接続を確立できませんでした。というエラー (SQLServerException)を回避するため、SQL Serverに 接続するためのJDBCドライバのバージョンを変更 --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>9.4.1.jre8</version> </dependency> <!-- MyBatisを利用するための設定 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.2</version> </dependency> <!-- テスト用の設定 start --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <!-- Spring Boot 2.7の場合、デフォルトでJUnit5を利用するための設定を除外 --> <exclusions> <exclusion> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> </exclusion> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> <exclusion> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> </exclusion> </exclusions> </dependency> <!-- JUnit5を利用するための設定 --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <scope>test</scope> </dependency> <!-- JUnit5でMockitoを利用するための設定 --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.6.28</version> <!-- PowerMockを利用するため、バージョンを変更 --> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>3.6.28</version> <!-- PowerMockを利用するため、バージョンを変更 --> <scope>test</scope> </dependency> <!-- JUnit4を利用するための設定(Mockitoも使える) --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <!-- JUnit4でPowerMockを利用するための設定 --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.2</version> <scope>test</scope> <exclusions> <exclusion> <artifactId>objenesis</artifactId> <groupId>org.objenesis</groupId> </exclusion> <exclusion> <artifactId>mockito-core</artifactId> <groupId>org.mockito</groupId> </exclusion> </exclusions> </dependency> <!-- テスト用の設定 end --> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
また、PowerMockを利用した際のソースコードは、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | package com.example.demo; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import java.time.LocalDate; import java.util.Map; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.validation.BindingResult; import static org.junit.Assert.assertEquals; //staticメソッドをMock化するにはPowerMockを利用 //@PrepareForTestアノテーションで、staticメソッドを含むクラスを指定 @RunWith(PowerMockRunner.class) @PrepareForTest({DateCheckUtil.class}) public class DemoServiceImplTestPowermock { /** * テスト対象のクラス * (今回はSpring Bootを利用しないため、Serviceではなく * ServiceImplを対象クラスに指定している) */ @InjectMocks private DemoServiceImpl demoServiceImpl; private DemoForm demoForm; private BindingResult bindingResult; /** * 初期化したMockオブジェクトを保持するクラス */ private AutoCloseable closeable; /** * 前処理(各テストケースを実行する前に行われる処理) */ @Before public void init() { /* @Mockアノテーションのモックオブジェクトを初期化 * これを実行しないと@Mockアノテーション、@InjectMocksを付与した * Mockオブジェクトが利用できない * MockitoAnnotations.initMocksメソッドは非推奨となったため * 代わりにopenMocksメソッドを利用 */ closeable = MockitoAnnotations.openMocks(this); //DateCheckUtilクラスをMock化 PowerMockito.mockStatic(DateCheckUtil.class); //テスト対象メソッドの引数を設定 demoForm = makeDemoForm(Long.valueOf(1), "テスト プリン" , LocalDate.of(2012, 1, 15), SexEnum.MAN); bindingResult = BindingResultModel.getBindingResult(); } /** * DemoServiceImplクラスのcheckFormメソッド(DateCheckUtil.checkDateが正常時)の確認 */ @Test public void testCheckFormNormal() { //DateCheckUtilメソッドをMock化し、0が返却されるように設定 PowerMockito.when(DateCheckUtil.checkDate( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(0); //テスト対象メソッドの実行 String returnVal = demoServiceImpl.checkForm(demoForm, bindingResult); //テスト対象メソッドを実行した結果、戻り値がconfirmであることを確認 assertEquals("confirm", returnVal); //テスト対象メソッドを実行した結果、bindingResultに //エラーメッセージが設定されないことを確認 Map<String, Object> mapObj = bindingResult.getModel(); assertEquals(0, mapObj.size()); } /** * DemoServiceImplクラスのcheckFormメソッド(DateCheckUtil.checkDateが異常時)の確認 */ @Test public void testCheckFormalDateError() { //DateCheckUtilメソッドをMock化し、4が返却されるように設定 PowerMockito.when(DateCheckUtil.checkDate( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(4); //テスト対象メソッドの実行 String returnVal = demoServiceImpl.checkForm(demoForm, bindingResult); //テスト対象メソッドを実行した結果、戻り値がinputであることを確認 assertEquals("input", returnVal); //テスト対象メソッドを実行した結果、resultに生年月日の日付が //不正な場合のエラーメッセージが設定されることを確認 Map<String, Object> mapObj = bindingResult.getModel(); BindingResultRejectValueModel resultModelYear = (BindingResultRejectValueModel) mapObj.get("birthYear"); assertEquals("validation.date-invalidate", resultModelYear.getErrorCode()); BindingResultRejectValueModel resultModelMonth = (BindingResultRejectValueModel) mapObj.get("birthMonth"); assertEquals("validation.empty-msg", resultModelMonth.getErrorCode()); BindingResultRejectValueModel resultModelDay = (BindingResultRejectValueModel) mapObj.get("birthDay"); assertEquals("validation.empty-msg", resultModelDay.getErrorCode()); } @Test public void testCheckFormDateCheckUtilArgs() { //DateCheckUtilメソッドをMock化し、0が返却されるように設定 PowerMockito.when(DateCheckUtil.checkDate( Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(0); //テスト対象メソッドの実行 String returnVal = demoServiceImpl.checkForm(demoForm, bindingResult); //DateCheckUtilが呼ばれたときの引数を取得するための設定 ArgumentCaptor<String> strYearArg = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> strMonthArg = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> strDayArg = ArgumentCaptor.forClass(String.class); //DateCheckUtilが1回呼ばれたことを確認 PowerMockito.verifyStatic(DateCheckUtil.class, Mockito.times(1)); DateCheckUtil.checkDate( strYearArg.capture(), strMonthArg.capture(), strDayArg.capture()); //DateCheckUtilの引数が2012年1月15日の年月日であることを確認 assertEquals("2012", strYearArg.getValue()); assertEquals("1", strMonthArg.getValue()); assertEquals("15", strDayArg.getValue()); //テスト対象メソッドを実行した結果、戻り値がconfirmであることを確認 assertEquals("confirm", returnVal); //テスト対象メソッドを実行した結果、bindingResultに //エラーメッセージが設定されないことを確認 Map<String, Object> mapObj = bindingResult.getModel(); assertEquals(0, mapObj.size()); } /** * 後処理(各テストケースを実行した前に行われる処理) * @throws Exception 何らかの例外 */ @After // JUnit4のアノテーション public void terminate() throws Exception { // Mockオブジェクトのリソースを解放 closeable.close(); } /** * Demoフォームオブジェクトを生成する * * @param id ID * @param name 名前 * @param birthDay 生年月日 * @param sexEnum 性別Enum * @return Demoフォームオブジェクト */ private DemoForm makeDemoForm(Long id, String name , LocalDate birthDay, SexEnum sexEnum) { DemoForm demoForm = new DemoForm(); if (id != null) { demoForm.setId(String.valueOf(id)); } demoForm.setName(name); if (birthDay != null) { demoForm.setBirthYear(String.valueOf(birthDay.getYear())); demoForm.setBirthMonth(String.valueOf(birthDay.getMonthValue())); demoForm.setBirthDay(String.valueOf(birthDay.getDayOfMonth())); } if (sexEnum != null) { demoForm.setSex(sexEnum.getSex()); demoForm.setSex_value(sexEnum.getSex_value()); } return demoForm; } } |
その他のソースコードについては、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-27-powermock/demoSpringTest/
サンプルプログラムの実行結果
サンプルプログラム「DemoServiceImplTestPowermock.java」を実行した結果は、以下の通りで、正常に実行できている。
サンプルプログラムのpom.xml(テスト用の設定)の完成経緯
サンプルプログラムのpom.xml(テスト用の設定)が完成するまでの経緯は、以下の通り。
1) pom.xmlの「テスト用の設定」に、以下のように、PowerMockの設定を追加する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | <!-- テスト用の設定 start --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <!-- Spring Boot 2.7の場合、デフォルトでJUnit5を利用するための設定を除外 --> <exclusions> <exclusion> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> </exclusion> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> <exclusion> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> </exclusion> </exclusions> </dependency> <!-- JUnit5を利用するための設定 --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <scope>test</scope> </dependency> <!-- JUnit5でMockitoを利用するための設定 --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <scope>test</scope> </dependency> <!-- JUnit4を利用するための設定(Mockitoも使える) --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <!-- JUnit4でPowerMockを利用するための設定 --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <!-- テスト用の設定 end --> |
2) この状態で「DemoServiceImplTestJunit4.java」を実行した場合、以下のようなエラーが発生する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | org.opentest4j.MultipleFailuresError: Multiple Failures (2 failures) java.lang.NoClassDefFoundError: Could not initialize class org.mockito.Mockito java.lang.NullPointerException: <no message> at org.junit.vintage.engine.execution.TestRun.getStoredResultOrSuccessful(TestRun.java:196) at org.junit.vintage.engine.execution.RunListenerAdapter.fireExecutionFinished(RunListenerAdapter.java:226) at org.junit.vintage.engine.execution.RunListenerAdapter.testFinished(RunListenerAdapter.java:192) at org.junit.vintage.engine.execution.RunListenerAdapter.testFinished(RunListenerAdapter.java:79) at org.junit.runner.notification.SynchronizedRunListener.testFinished(SynchronizedRunListener.java:87) at org.junit.runner.notification.RunNotifier$9.notifyListener(RunNotifier.java:225) at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72) at org.junit.runner.notification.RunNotifier.fireTestFinished(RunNotifier.java:222) at org.junit.internal.runners.model.EachTestNotifier.fireTestFinished(EachTestNotifier.java:38) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:372) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at org.junit.runner.JUnitCore.run(JUnitCore.java:115) at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:42) at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80) at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:72) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60) at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210) Suppressed: java.lang.NoClassDefFoundError: Could not initialize class org.mockito.Mockito at org.mockito.internal.configuration.MockAnnotationProcessor.processAnnotationForMock(MockAnnotationProcessor.java:33) at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:27) at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:24) at org.mockito.internal.configuration.IndependentAnnotationEngine.createMockFor(IndependentAnnotationEngine.java:44) at org.mockito.internal.configuration.IndependentAnnotationEngine.process(IndependentAnnotationEngine.java:72) at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:73) at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:47) at org.mockito.MockitoAnnotations.openMocks(MockitoAnnotations.java:81) at com.example.demo.DemoServiceImplTestJunit4.init(DemoServiceImplTestJunit4.java:56) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) ... 29 more Suppressed: java.lang.NullPointerException at com.example.demo.DemoServiceImplTestJunit4.terminate(DemoServiceImplTestJunit4.java:151) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.RunAfters.invokeMethod(RunAfters.java:46) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) ... 29 more |
3) この状態で「DemoServiceImplTestJunit5.java」を実行した場合、以下のように正常終了する。
4) pom.xmlの「テスト用の設定」の設定を、以下のように変更する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | <!-- テスト用の設定 start --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <!-- Spring Boot 2.7の場合、デフォルトでJUnit5を利用するための設定を除外 --> <exclusions> <exclusion> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> </exclusion> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> <exclusion> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> </exclusion> </exclusions> </dependency> <!-- JUnit5を利用するための設定 --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <scope>test</scope> </dependency> <!-- JUnit5でMockitoを利用するための設定 --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.6.28</version> <!-- PowerMockを利用するため、バージョンを変更 --> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>3.6.28</version> <!-- PowerMockを利用するため、バージョンを変更 --> <scope>test</scope> </dependency> <!-- JUnit4を利用するための設定(Mockitoも使える) --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <!-- JUnit4でPowerMockを利用するための設定 --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.2</version> <scope>test</scope> <exclusions> <exclusion> <artifactId>objenesis</artifactId> <groupId>org.objenesis</groupId> </exclusion> <exclusion> <artifactId>mockito-core</artifactId> <groupId>org.mockito</groupId> </exclusion> </exclusions> </dependency> <!-- テスト用の設定 end --> |
上記は、下記サイトの最後の方にある、XiaoZhiSnowさんのコメントを参考に設定している。
https://github.com/mockito/mockito/issues/2568
5) この状態で「DemoServiceImplTestJunit4.java」を実行した場合、以下のように正常終了する。
6) この状態で「DemoServiceImplTestJunit5.java」を実行した場合も、以下のように正常終了する。
また、「DemoServiceImplTestPowermock.java」を実行した結果は、「サンプルプログラムの実行結果」に記載の通りとなる。
要点まとめ
- Spring Boot 2.7を利用したJavaアプリケーションでJUnitを用いると、設定次第で、JUnit4とJUnit5の両方で動作した上で、PowerMockも利用できる。