Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PowerMock静态方法模拟不是';每个@InjectMocks调用都不考虑_Java_Unit Testing_Mockito_Junit4_Powermock - Fatal编程技术网

Java PowerMock静态方法模拟不是';每个@InjectMocks调用都不考虑

Java PowerMock静态方法模拟不是';每个@InjectMocks调用都不考虑,java,unit-testing,mockito,junit4,powermock,Java,Unit Testing,Mockito,Junit4,Powermock,我想编写一些单元测试,它们使用JUnit4.12、Mockito 1.9.5和PowerMock 1.6.1。 该类有一些用@Mock注释的字段,以及一些用@injectmock注释的字段。 用@InjectMocks注释的属性在某个点到达一个父构造函数,该父构造函数包含一些静态方法调用,应该用PowerMock进行模拟。 问题是第一个测试可以无缝地工作,而第二个测试似乎根本没有模仿静态方法 @RunWith(PowerMockRunner.class) @PrepareForTest({Sta

我想编写一些单元测试,它们使用JUnit4.12、Mockito 1.9.5和PowerMock 1.6.1。 该类有一些用@Mock注释的字段,以及一些用@injectmock注释的字段。 用@InjectMocks注释的属性在某个点到达一个父构造函数,该父构造函数包含一些静态方法调用,应该用PowerMock进行模拟。 问题是第一个测试可以无缝地工作,而第二个测试似乎根本没有模仿静态方法

@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticClass.class})
公共类TestClass{
@嘲弄
私有类属性1;
@注射模拟
私有SomeOtherClass属性2;
@课前
公共静态无效设置(){
mockStatic(StaticClass.class);
当(StaticClass.staticMethod(any(),any())。然后返回(newsomeconcreteClass());
}
@试验
公共void test1(){
assertEquals(attribute2.method1(),value1);
}
@试验
公共无效测试2(){
assertEquals(attribute2.method2(),value2);
}
}
公共类其他类{
私有类属性;
公共SomeOtherClass(){
SomeConcreteClass值=StaticClass.staticMethod(argument1,argument2);
value.someOtherMethod();
}
}
如前所述,第一个测试通过,并且PowerMock按预期模拟StaticClass.staticMethod()。 第二个测试没有通过,当对value调用其他方法时,它在第行抛出NullPointerException(因为value=null,因为PowerMock不再模拟StaticClass.staticMethod)。

如()中所述,PowerMock在每次测试之前重置模拟。

由于某种原因,它第一次起作用——存在 该问题的未解决错误报告()


这可以说是一个糟糕的设计,但实现您想要的功能的方法如下:
不依赖注释,而是手动设置模拟

private SomeClass attribute;
private SomeOtherClass testClass;

@Before
public void setUp() {
    PowerMockito.mockStatic(StaticClass.class);
    Mockito.when(StaticClass.staticMethod(anyString())).thenReturn(new SomeConcreteClass());

    attribute = Mockito.mock(SomeClass.class);      
    testClass = new SomeOtherClass();

    // assign mock manually
    testClass.attribute = attribute;
}
首选的方法是使用
SomeOtherClass
的构造函数提供
属性

但是,因为您似乎使用了空构造函数 您必须从外部设置值。
如果无法访问
属性
实例,您可能会被迫使用反射


更简洁的方法是重构您的构造函数
SomeOtherClass
,使其内部不使用静态方法。相反,将
SomeConcreteClass
作为参数传递给构造函数是一种方法


有些人甚至说你不应该在构造函数中有任何逻辑。

你是否尝试过使用
@Before
而不是
@BeforeClass
?可能的重复:使用@Before对我没有任何帮助,因为InjectMock是在每次测试运行之前调用的,之后调用方法之前调用的。但是我需要的对象的构造函数作为应该被模拟的静态方法调用。另一个注意事项是:在非模拟对象上使用
when
表达式
attribute2
(测试中的类)。这肯定会失败。你可能打错了,想改用
attribute1
?事实上,当用法是一个糟糕的例子时,它在实际代码中并不是这样。我只是把它放在那里,以证明我真的需要在attribute2实例中注入一些模拟。非常感谢你,它成功了!确实,它是一个糟糕的设计,但我需要在现有代码上编写测试,因此手动调用mocking方法确实起到了作用,因为我能够控制何时创建mock(在@Before方法中)。