繁体   English   中英

使用power mockito来抑制私有静态方法

[英]Using power mockito to suppress private static method

我举了一个代码来举例说明问题

public class SiteTranslator {
   Integer id;
   //Other fields
}

public class SiteUtil {

  private static SiteTranslator siteTranslator = getSiteTranslator();

  private static SiteTranslator getSiteTranslator()
  {
    SiteTranslator siteTranslator;
    //Logic involving network call
    return siteTranslator;
  }

  private static String getEnvironment()
  {
    String env = "";
    //Logic
    return env;
  }

  public static int getParent(int siteId)
  {
    int parentId = 0;
    //Logic using siteTranslator from getSiteTranslator()
    return parentId;
  }
}


public class SiteUtilTest {
  @Test
  public void test1()
  {
    try
    {
        PowerMockito.suppress(SiteUtil.class.getMethod("getSiteTranslator")); 
        BDDMockito.given(SiteUtil.getParent(1)).willReturn(6);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
  }
}

我们从getSiteTranslator()方法获得的SiteTranslator对象由我的公共函数getParent()使用。 由于getSiteTranslator()需要网络调用,因此需要对其进行抑制。 但是我得到以下错误

java.lang.NoSuchMethodException: SiteUtil.getSiteTranslator()

我相信问题是因为我试图模拟私有静态函数。 但是我无法将其改为公开。 有没有办法在当前状态下模拟代码。

其实,你并不需要Powermockito达到你所需要的。

目前,您认为需要Powermockito来抑制私有静态方法,但这绝对不是可行的方法。

相反,您应该重构代码以使其更容易测试:

  • 删除static限定符
  • 使用依赖注入

在这样的重构之后,你最终得到类似的东西(不需要嘲笑!):

public class SiteUtil {
    private SiteTranslator siteTranslator;

    public SiteUtil(SiteTranslator siteTranslator) {
        this.siteTranslator = siteTranslator;
    }

    public int getParent(int siteId) {
        int parentId = 0;
        // Logic using siteTranslator
        return parentId;
    }

    ...
}

现在你可以这样测试它:

public class SiteUtilSpec {
    private final SiteTranslator defaultTranslator = new DummySiteTranslator();

    @Test
    public void itShouldReturnTheSixthSiteWhenWeProvideTheFirstParent() {
        SiteUtil site = new SiteUtil(defaultTranslator);

        int parentId = site.getParent(1);

        assertEquals(6, parentId);
    }
}

DummySiteTranslator是一个假对象(也许它嵌入了一堆硬编码的翻译,可用于测试)但关键是这个对象永远不会进行任何网络调用! 使其安全,快速(非常适合测试)。

“Spotted”的答案已经指出了它,因为核心问题是:你完全没有理由创建了难以测试的代码。

使用这样的内部静态调用只会使您的程序难以测试; 并且惊喜:它也使得难以维护,增强和重用。 您需要转向Powermock的事实通常只是表明您的生产代码不好 现在,您可以选择使用PowerMock来“修复”该问题 ; 或者通过更改生产代码来解决问题 - 以示例代码的方式解决问题是一种不好的做法!

所以,另一个真正的教训是:你想花一些时间来学习如何编写没有这些问题的代码; 例如,通过观看那些视频

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM