JMockIt System.getenv(String)する方法?
-
06-07-2019 - |
質問
今持っているもの
テスト対象のクラスが依存するサードパーティのシングルトンインスタンスがあり、そのシングルトンはコンストラクタで System.getenv(String)
を使用しています。この呼び出しをモックすることは可能ですか?
これを試しました
JMockItの例
new Expectations()
{
System mockedSystem;
{
System.getenv( "FISSK_CONFIG_HOME" ); returns( "." );
}
};
ただし、 EXCEPTION_ACCESS_VIOLATION
が提供され、JVMがクラッシュします。
単体テストのシステム環境変数を設定する別の方法はありますか?
解決
この場合、JMockitがSystemクラスのすべてを再定義しないように、部分的なモックを使用する必要があります。次のテストに合格します。
@Test
public void mockSystemGetenvMethod()
{
new Expectations()
{
@Mocked("getenv") System mockedSystem;
{
System.getenv("envVar"); returns(".");
}
};
assertEquals(".", System.getenv("envVar"));
}
まもなく拡張機能を実装し、JREクラスをモックするときにこのような問題が発生しないようにします。リリース0.992または0.993で使用可能になります。
他のヒント
PowerMock は、システムクラスをモックできるようにシームします。
>他のオプション(サードパーティAPIの単体テストではない場合)は、 Facadeを作成することです。 素晴らしく、簡単にモック可能なインターフェースを持ち、テストクラスに本物ではなくこれを使用させるサードパーティAPI。
ああ、JMockItはこれもサポートしています: パッケージplaytest;
import static org.junit.Assert.*;
import mockit.*;
import mockit.integration.junit4.JMockit;
import org.junit.*;
import org.junit.runner.RunWith;
@RunWith(JMockit.class)
public class JMockItTest {
@Test
public void mockSystemGetEnv() {
Mockit.setUpMocks(MockSystem.class);
assertEquals("Bye", System.getenv("Hello"));
}
@MockClass(realClass = System.class)
public static class MockSystem {
@Mock
public static String getenv(String str) {
return "Bye";
}
}
}
環境を変更することはできませんが、アクセスを変更することはできます。 System.getenv()
への呼び出しをメソッドまたはヘルパークラスでラップしてから、それをモックします。
[編集]問題は、サードパーティライブラリのコードを変更する方法です。ここでの解決策は、Javaデコンパイラを使用してクラスを修正することです。必要に応じて、機能リクエストを送信することもできます。その新しいクラスをテストスイートに追加します。これにより、IDEがテスト用のクラスを見つけるはずです。
テストコードは実稼働に移行しないため、テストを実行でき、実稼働コードは元のライブラリを使用します。
しばらく前に System.exitをテストしたかったのですが、 カスタムSecurityManager 。呼び出しが行われていること、および呼び出しの引数を確認できますが、このメソッドを使用すると、呼び出しの戻り値をモックすることはできません。
@ Rogé rio answerの更新。
JMockit 1.25の場合は、MockUp APIを使用して実行する必要がありました。
@Test
public void mockSystemGetenvMethod(){
new MockUp<System>()
{
@Mock
public String getenv(final String string) {
return "";
}
};
assertEquals(".", System.getenv("envVar"));
}