我正在尝试运行Powermock测试,有两种测试方法。 第一种方法是正常测试,不需要嘲笑任何东西,并且可以独立工作。 第二种方法使用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")确定是否"域"可从当前网络访问:
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 :(得分:1)
从 import { Compiler, Component, Injector, VERSION, ViewChild, NgModule, NgModuleRef, OnInit, ViewContainerRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { CmsService } from "../../services/cms.service";
@Component({
selector: 'home-page',
template: `
<ng-container #vc></ng-container>
`
})
export class HomePageComponent implements OnInit {
constructor(private _compiler: Compiler, private _injector: Injector, private _m: NgModuleRef<any>) { }
ngOnInit() {
}
@ViewChild('vc', { read: ViewContainerRef }) vc;
ngAfterViewInit() {
const tmpCmp = Component({ moduleId: module.id, templateUrl: '../../../assets/HomePage/home-page-rbu.component.html' })(
class {
constructor(public cms: CmsService) { }
welcomeTXT: string;
advertismentTXT: string;
ngOnInit() {
this.cms.getCMSItemValue('welcomeTXT').subscribe(res => {
this.welcomeTXT = res;
});
this.cms.getCMSItemValue('advertismentTXT').subscribe(res => {
this.advertismentTXT = res;
});
}
});
@NgModule({
imports: [BrowserModule, RouterModule],
declarations: [tmpCmp],
providers: [CmsService]
})
class DynamicModule { }
this._compiler.compileModuleAndAllComponentsAsync(DynamicModule)
.then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = f.create(this._injector, [], null, this._m);
cmpRef.instance.name = 'dynamic';
this.vc.insert(cmpRef.hostView);
})
}
}
:
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
方法,以便它可以选择绕过缓存值。
FWIW,我使用您提供的代码重现了该问题,然后在allowInternalLogging
内禁用了缓存,并重新运行了他们通过的两个测试。
注意:allowInternalLogging()
方法会在inNetwork
:InetAddress
上进行此次调用,但您提供的测试用例需要InetAddress.getByName("some-hostname-which-we-know");
,因此不匹配测试用例和被测代码。