使用静态类进行测试,同时操作和非操作



我正在尝试运行一个 Powermock 测试,有 2 种测试方法。 第一种方法是正常的测试,没有模拟任何东西,并且独立工作正常。 第二种方法使用PowerMockito.mockStatic(InetAddress.class) - 它操纵主机地址,并且可以单独工作。 当我同时运行两个测试时,其中一个方法失败,具体取决于哪个方法首先运行。第一种测试方法总是成功的,第二种测试方法失败。

如何避免此问题?

@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("domain")确定是否可以从当前网络访问"domain":

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

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这具有任何后续调用重用第一次调用生成的结果的效果。

  • 如果首先调用test_nok,则会导致ClassForTest.internalLogging设置为false从而导致test_is_ok失败,因为它期望true
  • 如果首先调用test_is_ok,则会导致ClassForTest.internalLogging设置为true从而导致test_nok失败,因为它期望false

如果需要多次调用此方法并期望不同的结果,则必须在每次调用之间重置ClassForTest.internalLogging,或者以某种方式参数化allowInternalLogging方法,以便它可以选择性地绕过缓存的值。

FWIW,我使用您提供的代码重现了该问题,然后在allowInternalLogging()内禁用了缓存,并在重新运行两个测试时通过了。

附带说明:inNetwork方法对InetAddress: 进行此调用:InetAddress.getByName("some-hostname-which-we-know");但您提供的测试用例期望:InetAddress.getLocalHost();因此测试用例和待测试代码之间存在不匹配。