我已经用我的代码做了一个小例子来说明这个问题
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();
}
}
}
我的公共(public)函数 getParent() 使用我们从 getSiteTranslator() 方法获得的 SiteTranslator 对象。由于 getSiteTranslator() 需要网络调用,因此需要将其抑制。但是我收到以下错误
java.lang.NoSuchMethodException: SiteUtil.getSiteTranslator()
我认为问题出在我试图模拟私有(private)静态函数。但是我不能将其更改为公开。有没有办法在当前状态下模拟代码。
最佳答案
事实上,您不需要需要 Powermockito 来实现您的需要。
目前,您认为您需要 Powermockito 来抑制私有(private)静态方法,但这绝对不是正确的方法。
相反,您应该重构代码以使其更易于测试:
- 删除
static
限定符 - 使用依赖注入(inject)
在这样的重构之后,你最终会得到类似的东西(不需要模拟!):
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
是一个假对象(也许它嵌入了一堆对测试有用的硬编码翻译)但关键是这个对象从不进行任何网络调用!使其使用安全且快速(非常适合测试)。
关于java - 使用 power mockito 抑制私有(private)静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39720757/