如何 mock/spy/stub 保护 super class 的方法
How to mock/spy/stub protected methods of super class
我实现了 class B,它是现有摘要 class A
的子 class
摘要class(实质):
public abstract class A {
public A(Properties p, ArrayList<XXX> list) {
...
}
// There is no 0-arg constructor
protected int doSomeWork() {
return ...;
}
protected SomeObject[] findObjectsByQuery(String query) {
return ...;
}
}
我自己的class
public class B extends A {
// this is the method I want to test
protected int doSomeWork() {
...
// calling method of super class
// this call I want to mock/stub/whatever
// to either return null or a mock object
SomeObject[] myobjects = findObjectsByQuery(queryString);
...
}
}
如您所见,我要测试的方法也被保护了。这就是为什么我创建了一个内部 class Btest,它继承自 B 仅用于测试目的:
private class Btest extends B {
public Btest(Properties prop) {
super(prop, null);
}
public int doSomeWork() {
return super.doSomeWork();
}
}
我的测试方法是使用 Mockito 和 PowerMock。这是我目前所拥有的:
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class Tester {
@Test
public void testWrongQueryString() throws Exception {
Properties prop = new Properties();
Btest testObject = new Btest(prop);
// what am I supposed to do here?
// essentially I want to do something in the lines of
// PowerMockito.when(/* there is a call to A.findObjectsByQuery or B.findObjectsByQuery with parameter "QueryString" */)
// .thenReturn(null);
int result = testObject.doSomeWork();
Assert.assertEquals(2, result);
}
}
这是我尝试过的:
// gives an InvocationTargetException
Btest spy = PowerMockito.spy(testObject);
PowerMockito.when(spy, "findObjectsByQuery", "QueryString").thenReturn(null);
// will not return NULL
A mock = Mockito.mock(A.class);
PowerMockito.when(mock, "findObjectsByQuery", "QueryString").thenReturn(null);
我该怎么办?
我觉得应该是这样的:
Btest spy = PowerMockito.spy(testObject);
PowerMockito.doReturn(null).when(spy, "findObjectsByQuery");
我的问题是我用 testObject.doSomeWork()
而不是 spy.doSomeWork()
调用了要测试的方法
它是这样工作的:
Btest spy = PowerMockito.spy(testObject);
PowerMockito.doReturn(null).when(spy, "findObjectsByQuery", Mockito.someString());
与
int result = spy.doSomeWork();
我实现了 class B,它是现有摘要 class A
的子 class摘要class(实质):
public abstract class A {
public A(Properties p, ArrayList<XXX> list) {
...
}
// There is no 0-arg constructor
protected int doSomeWork() {
return ...;
}
protected SomeObject[] findObjectsByQuery(String query) {
return ...;
}
}
我自己的class
public class B extends A {
// this is the method I want to test
protected int doSomeWork() {
...
// calling method of super class
// this call I want to mock/stub/whatever
// to either return null or a mock object
SomeObject[] myobjects = findObjectsByQuery(queryString);
...
}
}
如您所见,我要测试的方法也被保护了。这就是为什么我创建了一个内部 class Btest,它继承自 B 仅用于测试目的:
private class Btest extends B {
public Btest(Properties prop) {
super(prop, null);
}
public int doSomeWork() {
return super.doSomeWork();
}
}
我的测试方法是使用 Mockito 和 PowerMock。这是我目前所拥有的:
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class Tester {
@Test
public void testWrongQueryString() throws Exception {
Properties prop = new Properties();
Btest testObject = new Btest(prop);
// what am I supposed to do here?
// essentially I want to do something in the lines of
// PowerMockito.when(/* there is a call to A.findObjectsByQuery or B.findObjectsByQuery with parameter "QueryString" */)
// .thenReturn(null);
int result = testObject.doSomeWork();
Assert.assertEquals(2, result);
}
}
这是我尝试过的:
// gives an InvocationTargetException
Btest spy = PowerMockito.spy(testObject);
PowerMockito.when(spy, "findObjectsByQuery", "QueryString").thenReturn(null);
// will not return NULL
A mock = Mockito.mock(A.class);
PowerMockito.when(mock, "findObjectsByQuery", "QueryString").thenReturn(null);
我该怎么办?
我觉得应该是这样的:
Btest spy = PowerMockito.spy(testObject);
PowerMockito.doReturn(null).when(spy, "findObjectsByQuery");
我的问题是我用 testObject.doSomeWork()
而不是 spy.doSomeWork()
它是这样工作的:
Btest spy = PowerMockito.spy(testObject);
PowerMockito.doReturn(null).when(spy, "findObjectsByQuery", Mockito.someString());
与
int result = spy.doSomeWork();