【问题标题】:How to JMockIt System.getenv(String)?如何 JMockIt System.getenv(String)?
【发布时间】:2009-10-27 10:17:02
【问题描述】:

我现在拥有的

我有一个第 3 方单例实例,我的测试类依赖于该实例,并且该单例在其构造函数中使用 System.getenv(String)。可以模拟这个调用吗?

我试过了

JMockIt 示例

    new Expectations()
    {

        System mockedSystem;
        {
            System.getenv( "FISSK_CONFIG_HOME" ); returns( "." );
        }
    };

但它给了我一个EXCEPTION_ACCESS_VIOLATION 并使 JVM 崩溃。

还有其他方法可以为单元测试设置系统环境变量吗?

【问题讨论】:

    标签: java unit-testing jmockit


    【解决方案1】:

    在这种情况下,您需要使用部分模拟,以便 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 版本中可用。

    【讨论】:

      【解决方案2】:

      PowerMock 接缝能够模拟系统类。

      您的另一个选择(假设您没有对第 3 方 API 进行单元测试)是为 Facade 创建一个具有良好、易于模拟的接口的第 3 方 API,并让您的测试类使用它而不是真实的东西.

      哦,JMockIt 也支持这个: 打包播放测试;

      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";
        }
       }
      
      }
      

      【讨论】:

        【解决方案3】:

        您无法更改环境,但可以更改对它的访问:只需将对 System.getenv() 的调用包装在方法或帮助器类中,然后对其进行模拟。

        [编辑] 现在您的问题是如何更改第三方库的代码。这里的解决方案是使用 Java 反编译器并修复类。如果需要,您也可以发送功能请求。将该新类添加到您的测试套件中。这应该会让你的 IDE 找到测试的类。

        由于测试代码没有投入生产,您可以运行测试,生产代码将使用原始库。

        【讨论】:

        • 我认为这意味着他不能这样做,因为它在第三方库中
        • 反编译类并修复它。
        【解决方案4】:

        不久前我想test System.exit,并通过使用custom SecurityManager 找到了解决方案。您可以验证正在进行调用,以及调用的参数,但使用此方法,您无法模拟调用的返回值。

        【讨论】:

          【解决方案5】:

          @Rogério 答案的更新。

          在我使用 JMockit 1.25 的情况下,我必须使用 MockUp API:

          @Test
          public void mockSystemGetenvMethod(){
              new MockUp<System>()
              {
                  @Mock
                  public String getenv(final String string) {
                      return "";
                  }
              };
          
              assertEquals(".", System.getenv("envVar"));
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-16
            • 2018-09-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多