例如,我有这个课程:
public class A {
private List<String> list;
public A(B b){
list = b.getList();
}
public List<String> someMethod(){
return list;
}
}
我想在不调用构造函数的情况下对单元测试someMethod
进行单元测试。我使用 reflection 来设置list
。
问题在于我不想创建B
类对象而且我无法模拟它,因为它会导致NPE。
所以我的问题是:
如何在不调用someMethod
的构造函数的情况下测试A
?有没有办法模拟A类,并且没有失去调用方法的可能性?
创建零参数的构造函数不是解决方案。
注意: 我不想要更改A类的任何部分。我问的是,如果不在A类中添加或更改任何内容,是否可以执行此测试。
答案 0 :(得分:5)
您可以在不调用Mockito构造函数的情况下测试A类。不确定我是否真的了解您的要求,但以下代码对我有用。
import org.junit.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class ATest {
@Test
public void test() {
A a = mock(A.class);
when(a.someMethod()).thenCallRealMethod();
List<String> listInA = new ArrayList<String>();
ReflectionTestUtils.setField(a, "list", listInA);
assertThat(a.someMethod(), is(listInA));
}
}
答案 1 :(得分:4)
你应该把合作者嘲笑到你的班级 - 这意味着你可以创建一个被测试的类的实例,并传入模拟,配置为做正确的事情&#39;什么时候调用它的方法。
在您的示例中,您想要创建一个模拟B,并像这样使用它:
@RunWith(MockitoJUnitRunner.class)
class myTest {
@Mock private B b;
public void someMethod() {
doReturn(new ArrayList<String>()).when(b).getList();
A a = new A(b);
assertEquals("result", a.someMethod().get(0));
}
}
答案 2 :(得分:-2)
我不想创建B类对象
添加一个不需要B的构造函数或工厂方法。
public A(B b){
this(b.getList());
}
/* package local */ A(List<String> list){
this.list = list;
}
通过使构造函数包为local,可以通过同一个包中的单元测试来访问它。
如何在不调用A的构造函数的情况下测试someMethod?
您可以使用
A a = theUnsafe.allocateInstance(A.class);
但不建议这样做,除非您没有其他选择,例如反序列化。