インラインで初期化されているフィールド変数をモックするにはどうすればよいですか?
例えば.
class Test {
private Person person = new Person();
...
public void testMethod() {
person.someMethod();
...
}
}
ここで私はモックしたいperson.someMethod()メソッドのテスト中-Test#testMethod。
そのために、個人変数の初期化を模擬する必要があります。どんな手掛かり?
編集:Personクラスを変更することはできません。
私はすでにこの問題の解決策を見つけましたが、ここに投稿するのを忘れました。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Test.class })
public class SampleTest {
@Mock
Person person;
@Test
public void testPrintName() throws Exception {
PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
Test test= new Test();
test.testMethod();
}
}
このソリューションの重要なポイントは次のとおりです。
PowerMockRunnerでテストケースを実行する:@RunWith(PowerMockRunner.class)
プライベートフィールドの操作のためにTest.class
を準備するようにPowermockに指示します:@PrepareForTest({ Test.class })
最後に、Personクラスのコンストラクターをモックします。
PowerMockito.mockStatic(Person.class);
PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
Mockitoには、いくつかの反射ボイラープレートコードを保存するヘルパークラスが付属しています。
import org.mockito.internal.util.reflection.Whitebox;
//...
@Mock
private Person mockedPerson;
private Test underTest;
// ...
@Test
public void testMethod() {
Whitebox.setInternalState(underTest, "person", mockedPerson);
// ...
}
更新:残念ながら、mockitoチームは クラスを削除する をMockito 2に決定しました。コード、別のライブラリを使用する(例: Apache Commons Lang )、または単に Whitebox クラスを盗む( MITライセンス )。
更新2:JUnit 5には、独自の ReflectionSupport および AnnotationSupport が役立つクラスが付属しています。さらに別のライブラリを使用しないようにしてください。
パーティーにかなり遅れましたが、私はここで打たれ、友人から助けを受けました。事はPowerMockを使用することではありませんでした。これは、Mockitoの最新バージョンで動作します。
Mockitoにはこのorg.mockito.internal.util.reflection.FieldSetter
が付属しています。
基本的には、リフレクションを使用してプライベートフィールドを変更するのに役立ちます。
これがあなたの使い方です-
@Mock
private Person mockedPerson;
private Test underTest;
// ...
@Test
public void testMethod() {
FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person", mockedPerson);
// ...
verify(mockedPerson).someMethod()
}
これにより、モックオブジェクトを渡して、後で検証することができます。
参照:
https://www.codota.com/code/Java/methods/org.mockito.internal.util.reflection.FieldSetter/set
Spring Testを使用する場合org.springframework.test.util.ReflectionTestUtils
ReflectionTestUtils.setField(testObject, "person", mockedPerson);
次のコードを使用して、RESTクライアントモックでマッパーを初期化できます。 mapper
フィールドはプライベートであり、単体テストのセットアップ中に設定する必要があります。
import org.mockito.internal.util.reflection.FieldSetter;
new FieldSetter(client, Client.class.getDeclaredField("mapper")).set(new Mapper());
すべてのテストで変数に同じ値を設定する必要がある場合は、@ Jardaのガイドを使用してこれを定義できます。
@Before
public void setClientMapper() throws NoSuchFieldException, SecurityException{
FieldSetter.setField(client, client.getClass().getDeclaredField("mapper"), new Mapper());
}
ただし、プライベート値を異なる値に設定する場合は注意が必要です。彼らがプライベートである場合は、何らかの理由です。
たとえば、ユニットテストでスリープの待機時間を変更する場合などに使用します。実際の例では10秒間スリープしたいのですが、単体テストではすぐに満足します。統合テストでは、実際の値をテストする必要があります。