java - Java - 用于多个测试的模拟私有静态构造函数
问题描述
我是java测试的新手,现在一直在摆弄这个,没有运气,我有以下类:
public class Bar {
public Object doSomething(int a, String b){
return "something";
}
public Object doSomethingElse(int a, int b, String c){
return "something else";
}
}
public class Foo {
private static Bar bar = new Bar();
public static void start(int a, int b, String c){
if(a == 1) { // some calculated condition
bar.doSomething(a, c);
} else {
bar.doSomethingElse(a, b, c);
}
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(Foo.class)
public class FooTest {
@Test
public void somethingTest() throws Exception {
Bar barMock = createMock(Bar.class);
expectNew(Bar.class).andReturn(barMock);
expect(barMock.doSomething(1, "xxx")).andReturn("ABC");
replay(barMock, Bar.class);
Foo.start(1, 2, "xxx");
verify(barMock, Bar.class);
}
@Test
public void somethingElseTest() throws Exception {
Bar barMock = createMock(Bar.class);
expectNew(Bar.class).andReturn(barMock);
expect(barMock.doSomethingElse(0, 2,"xxx")).andReturn("ABC");
replay(barMock, Bar.class);
Foo.start(0, 2, "xxx");
verify(barMock, Bar.class);
}
}
单独运行测试,但不是整个班级,我认为这与:
private static Bar bar = new Bar();
但我不是 100% 确定。无论哪种方式,假设我无法更改 foo / bar 类,我该如何解决这个问题?
解决方案
您面临的问题是 a 的static
字段class
仅初始化一次。因此第一个测试创建了一个新Bar
对象,但是这个模拟在所有其他测试中都存在,因为没有触发新的创建。
相反,您应该使用为每个测试Reflections
设置private static
字段。PowerMock
为您提供了一个名为Whitebox
.
另请注意,只有在该类中setInternalState
只有一个对象实例时才有效。Bar
如果有多个,您将需要依赖普通的 Java 反射类。
示例见下:
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("test.Foo") // optional, only required if the Bar class could not be created normally.
public class StaticTest {
@Test
public void somethingTest() throws Exception {
Bar barMock = createMock(Bar.class);
Whitebox.setInternalState(Foo.class, barMock);
expect(barMock.doSomething(1, "xxx")).andReturn("ABC");
replay(barMock, Bar.class);
Foo.start(1, 2, "xxx");
verify(barMock, Bar.class);
}
@Test
public void somethingElseTest() throws Exception {
Bar barMock = createMock(Bar.class);
Whitebox.setInternalState(Foo.class, barMock);
expect(barMock.doSomethingElse(0, 2,"xxx")).andReturn("ABC");
replay(barMock, Bar.class);
Foo.start(0, 2, "xxx");
verify(barMock, Bar.class);
}
}
我将它与静态初始化的抑制结合起来,但严格来说,这对您的测试来说不是必需的,因为Bar
无论如何创建类都会成功。
Bar
只有在无法创建类的情况下才应使用注释。请注意,您需要在此处输入包括包名称在内的完全限定名称(我假设包是test
)。
推荐阅读
- python - 从空数组创建 RGB 颜色
- python - Find_all_siblings 没有从 Python Beautiful Soup 中的论坛帖子中找到所有表行兄弟姐妹
- bash - 读取文件名中的空格时
- r - 规范化 R 中的俄语字符
- python - django 1.11 中 SelectDateWidget 的空选项
- python - Python - 将字符串转换为简单的 YYYY 日期格式
- memory-management - 内存管理单元如何将虚拟地址映射到物理地址
- python - Python - PyPDF2 遗漏了大量文本。Windows上有任何替代方案吗?
- java - Java线程:3个Java线程之间的通信
- python - 对于 python 3,我不断得到一个带有新行的字符串值