2017-12-13 30 views
1

私はPowermockテストを実行しようとしていますが、2つのテスト方法があります。 最初の方法は、何かを嘲笑せずに通常のテストであり、独立して動作します。 2番目の方法では、PowerMockito.mockStatic(InetAddress.class)を使用します。この方法では、ホストアドレスを操作します。 両方のテストを同時に実行すると、どちらが最初に実行されたかによって、いずれかの方法が失敗します。最初のテスト方法は常に成功し、2番目のテスト方法は失敗します。静的クラスを操作してテストしたものではありません

どうすればこの問題を回避できますか?

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ClassForTest.class) 
@FixMethodOrder(MethodSorters.NAME_ASCENDING) 
public class TestForClassForTest{ 

    @Test 
    public void test_is_ok() throws Exception { 
     boolean internalLogging = ClassForTest.allowInternalLogging(); 
     Assert.assertTrue(internalLogging); 
    } 

    @Test 
    public void test_nok() throws Exception { 
     PowerMockito.mockStatic(InetAddress.class); 
     PowerMockito.when(InetAddress.getLocalHost()).thenReturn(inetAddress); 
     when(inetAddress.getHostAddress()).thenReturn("1.1.1.1"); 

     boolean internalLogging = ClassForTest.allowInternalLogging(); 
     Assert.assertFalse(internalLogging); 
    } 
} 

方法 "allowInternalLogging" は "ドメイン" は、現在のネットワークから到達可能であるか否かをInetAddress.getByName( "ドメイン")を用いて、決定:

public final class ClassForTest { 

    private static Boolean internalLogging; 

    private ClassForTest() { 
    } 


    private static boolean inNetwork() { 
     // By default no hosts should be found! 
     boolean hostFound = false; 

     try { 
      // "Ping" the hosts by looking up the inetaddress 
      final InetAddress address = InetAddress.getByName("some-hostname-which-we-know"); 

      // If the address is not null, we were able to lookup the 
      // specified hostname. 
      if (address != null) { 
       hostFound = true; 
      } 

     } catch (final UnknownHostException ex) { 
      // Host could not be found! 
      hostFound = false; 
     } 

     return hostFound; 
    } 


    public static Boolean allowInternalLogging() { 
     if (internalLogging == null) { 
      try { 
       internalLogging = inNetwork(); 
      } catch (Exception e) { 
       internalLogging = false; 
       LOGGER.debug("Could not determine logging granularity", e); 
      } 
     } 
     return internalLogging; 
    } 
} 
+0

"必要ならば具体的な例を提供することができます" ...はい、お願いします:) – glytching

+0

@glytching done – Madrugada

+0

このクラスを使用して再現しようとする人がいなければ、 'ClassForTest.allowInternalLogging()'の実装を見ると便利でしょう。質問で提供されるコードは、実装を推測する必要があります。 – glytching

答えて

1

ClassForTestの実装から:

public static Boolean allowInternalLogging() { 
    if (internalLogging == null) { 
     try { 
      internalLogging = inNetwork(); 
     } catch (Exception e) { 
      internalLogging = false; 
      LOGGER.debug("Could not determine logging granularity", e); 
     } 
    } 
    return internalLogging; 
} 

このメソッドは効果的にinNetworkの結果をキャッシュします。これは、後続の呼び出しが最初のca ll。

  • test_nok場合は、それがそれによってtrueを期待するのでtest_is_okが失敗する原因falseに設定するClassForTest.internalLoggingを引き起こす最初に呼び出されます。
  • test_is_okが最初に呼び出された場合、ClassForTest.internalLoggingtrueに設定され、が予想されるため、test_nokが失敗する原因となります。

あなたは、このメソッドを複数回呼び出すと、異なる結果を期待する必要があるなら、あなたは各呼び出しの間ClassForTest.internalLoggingをリセットするか、何とかそれは、必要に応じて、キャッシュされた値をバイパスできるようにallowInternalLogging方法をparameteriseするかがあります。

FWIWでは、指定したコードを使用して問題を再現し、allowInternalLogging()のキャッシングを無効にして、両方のテストを再実行すると合格しました。サイドノートでは

inNetwork方法はInetAddressにこの呼び出しを行いますInetAddress.getByName("some-hostname-which-we-know");しかし、あなたが期待するが提供されるテストケース:InetAddress.getLocalHost();ので、テストケースとコード被試験との間に不一致があります。

+0

ありがとうございました!確かにそうです!私は静的なクラスの嘲笑によって、それが何かをするかもしれないと思って誘惑された。 – Madrugada

関連する問題