我正在编写与第三方Java SDK连接的应用程序。我目前正在使用Mockito和PowerMock编写单元测试。我遇到了一个模拟sdk提供的类的问题。虚拟类看起来像这样:
class A{
public static A getInstance() {
...
}
public A(){
...
}
}
我试图模拟B类,它既调用A的构造函数,又调用A中的静态方法。
class B{
public String doSomething(){
A test1 = A.getInstance();
A test2 = new A();
...
}
}
我需要能够在B&B方法中模拟test1和test2对象,所以我尝试按如下方式编写测试:
@RunWith( PowerMockRunner.class )
@PrepareForTest( B.class )
public class BTest{
@PrepareForTest( A.class )
@Test
public void testdoSomething() {
A mockedTest1 = Mockito.mock(A.class);
A mockedTest2 = Mockito.mock(A.class);
PowerMockito.whenNew(A.class).withAnyArguments().thenReturn(mockedTest2)
PowerMockito.mockStatic( A.class )
PowerMockito.when( A.getInstance()).thenAnswer(mockedTest1)
B b = new B();
b.doSomething();
}
在静态方法被模拟时,构造函数不是。但是,如果我不尝试模拟构造函数(即删除PrepareForTest注释并按如下方式更改代码:)
@RunWith( PowerMockRunner.class )
@PrepareForTest( B.class )
public class BTest{
@Test
public void testdoSomething() {
A mockedTest1 = Mockito.mock(A.class);
A mockedTest2 = Mockito.mock(A.class);
PowerMockito.whenNew(A.class).withAnyArguments().thenReturn(mockedTest2)
B b = new B();
b.doSomething();
}
我可以正确地模拟构造函数。有没有Powermock可以防止同时模拟构造函数和静态方法?或者我有什么遗失的东西?
感谢。
答案 0 :(得分:0)
你自己很亲密,但你必须考虑一些事情,以使所有部分适合这个难题:
1)Powermock documentation for mocking constructors
- 在测试用例的类级别使用@PrepareForTest( ClassThatCreatesTheNewInstance.class )注释。
醇>
2)Powermock documentation for mocking static methods
- 在测试用例的类级别使用@PrepareForTest( ClassThatContainsStaticMethod.class )注释
醇>
到目前为止,我们知道我们需要准备测试A.class
(静态方法)&你做了B.class
(构造函数),但是你在类级别和测试方法级别都使用了@PrepareForTest
。
3)Powermock javadoc for @PrepareForTest
此注释可以放在测试类和单独的测试方法中。如果放在类中,则此测试类中的所有测试方法都将由PowerMock处理(以允许可测试性)。 要覆盖单个方法的此行为,只需在特定测试方法上放置@PrepareForTest注释即可。 这在例如您想要在测试方法A中修改类X但在测试方法B中希望X保持原样的情况下非常有用。
总之,要么在班级使用@PrepareForTest({A.class, B.class})
,要么在方法层面使用,一切都应该没问题。