閲覧いただきありがとうございます!
前提・実現したいこと
JUnitを使用し、テストを作成しています。
クラス内で使用してるprivate final定数を、privateメソッドの中で値を条件分岐によってセットしています。
正しい値がセットされていることを確認したいですが、privateメソッドのテストをする為、
クラスをスパイ化していると、private定数が取得できません。
発生している問題・エラーメッセージ
java.lang.NoSuchFieldException
該当のソースコード
Java
1@Component 2@RequiredArgsConstructor 3public Class TargetClass { 4 private final SampleModel sampleModel; 5 6 public void public_sample() { 7 sampleModel.setGreet(""); 8 9 private_sample("John"); 10 private_sample("Mike"); 11 } 12 13 private void private_sample(String name) { 14 if (name.equal("John")_ { 15 sampleModel.setGreeet("Hello, John!") 16 } else { 17 sampleModel.setGreet("Who are you?") 18 } 19 } 20} 21 22@Component 23@Data 24public class SampleModel { 25 private String greet; 26} 27 28 29@RunWith(PowerMockRunner.class) 30@PrepareForTest({ TargetClass.class }) 31public class SampleTest { 32 @InjectMocks 33 private TargetClass _logic; 34 35 @Test 36 public void public_test() { 37 // private methodの呼び出しがある為spy 38 _logic = PowerMockito.spy(_logic); 39 40 // private_sampleをアクセス可能にする 41 Method privateMethod = TargetClass.class.getDeclaredMethod("private_sample", String.class); 42 privateMethod.setAccessible(true) 43 44 // sampleModelをアクセス可能にする 45 Field field = _logic.getClass().getDeclaredField("sampleModel"); // ここでエラーになる 46 field.setAccessible(true); 47 field.set(_logic, new SampleModel()); 48 49 // actual 50 _logic.public_sample(); 51 52 // verify 53 54 } 55 56 @Test 57 public void private_test() { 58 // private methodのテストの為spy 59 _logic = PowerMockito.spy(_logic); 60 61 // private_sampleをアクセス可能にする 62 Method privateMethod = TargetClass.class.getDeclaredMethod("private_sample", String.class); 63 privateMethod.setAccessible(true) 64 65 // sampleModelをアクセス可能にする 66 Field field = _logic.getClass().getDeclaredField("sampleModel"); // ここでエラーになる 67 field.setAccessible(true); 68 field.set(_logic, new SampleModel()); 69 70 // actual 71 targetMethod.invoke(_logic, "John") 72 SampleModel actualModel = (SampleModel) field.get)_logic); 73 74 // expect 75 SampleModel expect = new SampleModel(); 76 expect.setGreeet("Hello, John!") 77 78 // verify 79 assertThat(actualModel, is(expect)); 80 } 81} 82
試したこと
private_testでは下記を削除するとうまくいきました。
_logic = PowerMockito.spy(_logic);
が、削除が必要な意味が分からないです。
また、なぜないのか?確認する為、getDeclaredFields()で中身を見てみたところ、
filedsにはMockが入っているようでした。(※下記コード)
Java
1 @Test 2 public void private_test() { 3 // private methodのテストの為spy 4 _logic = PowerMockito.spy(_logic); 5 6 // private_sampleをアクセス可能にする 7 Method privateMethod = TargetClass.class.getDeclaredMethod("private_sample", String.class); 8 privateMethod.setAccessible(true) 9 10 // sampleModelをアクセス可能にする 11 Field[] fields = _logic.getClass().getDeclaredFields(); // 配列で取ってみる 12 field.setAccessible(true); 13 field.set(_logic, new SampleModel()); 14 15 // actual 16 targetMethod.invoke(_logic, "John") 17 SampleModel actualModel = (SampleModel) field.get)_logic); 18 19 // expect 20 SampleModel expect = new SampleModel(); 21 expect.setGreeet("Hello, John!") 22 23 // verify 24 assertThat(actualModel, is(expect)); 25 }
補足情報(FW/ツールのバージョンなど)
Spring Framework
どうすれば、public_sample / private_sameple共にテストを通せるのかご教授いただければと思います。
よろしくお願いいたします。
あなたの回答
tips
プレビュー