我有一个测试其他类方法的测试类
其他类的结构如下
@Component
public abstract class ParentOpManager{
@Autowired
private ProcessorRequestWrapper processorRequestWrapper;
@Autowired
private XYProcessor xyProcessor;
}
@Component("childManager")
public class ChildOperationManager extends ParentOpManager{
}
public abstract class ParentClass{
protected final RequestWrapper requestWrapper;
protected final ParentOpManager parentOpManager;
public ParentClass(final RequestWrapper requestWrapper, final ParentOpManager parentOpManager){
this.requestWrapper = requestWrapper;
this.parentOpManager = parentOpManager;
}
}
我还有,扩展这个类的子类
public class ChildClass extends ParentClass{
@Autowired
private NinjaManager ninjaManager;
@Autowired
public ChildClass(final RequestWrapper requestWrapper, @Qualifier("childManager")final ParentOpManager parentOpManager){
super(requestWrapper, parentOpManager);
}
public void methodA() throws Exception {
Request item = requestWrapper.findItem(); // Problem place 1
}
public void methodB() throws Exception {
Request item = ninjaManager.findItem(); // Problem place 2
}
}
我需要测试ChildClass
的方法。为此我写了一个测试类。
//@RunWith(MockitoJunitRunner.class)
//@ContextConfiguration
public class TestClass{
@Mock
ChildOperationManager chOpManager;
@Mock
RequestWrapper requestWrapper;
@InjectMocks
ChildClass childObject;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
@Test
public void testSomeMethodA() throws Exception{
childObject.methodA();
}
}
所以,问题是当我从测试类开始类methodA时,requestWrapper是NULL。我不明白为什么会这样?
编辑:
如果我喜欢
@Mock
ChildOperationManager chOpManager = new ChildOperationManager();
@Mock
RequestWrapper requestWrapper;
@InjectMocks
ChildClass childObject = new childObject(requestWrapper, chOpManager);
问题接缝有待解决。还有一些其他问题可能是一些许可问题。但你认为这样做是好方法吗?
答案 0 :(得分:1)
您的错误是:
@Autowired
public ChildClass(final RequestWrapper requestWrapper, @Qualifier("childManager")final ParentOpManager parentOpManager){
super(requestWrapper, parentOpManager);
}
public void methodA() throws Exception {
Request item = requestWrapper.findItem(); // this requestWrapper is null
}
您没有在子项中分配requestWrapper引用。所以它仍然是空的。
您应该从子项中删除成员变量requestWrapper
和parentOpManager
。通过这种方式,您将使用已初始化的父对象。
答案 1 :(得分:1)
问题是Mockito试图在第一步中通过构造函数注入mock。
public class DefaultInjectionEngine {
public void injectMocksOnFields(Set<Field> needingInjection, Set<Object> mocks, Object testClassInstance) {
MockInjection.onFields(needingInjection, testClassInstance)
.withMocks(mocks)
.tryConstructorInjection() <-- Here
.tryPropertyOrFieldInjection()
.handleSpyAnnotation()
.apply();
}
}
如果它找到了正确的构造函数,它不会尝试通过属性或字段注入模拟。
在你的情况下,你有ChildClass的构造函数,它是由Mockito选择的,但是你没有初始化ChildClass中的字段。
作为解决方法,您可以通过这种方式解决它(只是不要使用mockito注入):
RequestWrapper wrapper;
ChildOperationManager childOperationManager;
ChildClass childObject;
@Before
public void setUp() {
wrapper = Mockito.mock(RequestWrapper.class);
childOperationManager = Mockito.mock(ChildOperationManager.class);
childObject = new ChildClass(wrapper, childOperationManager );
}