[英]Mocking Chained calls in Concrete Class Mockito
I am using Mockito services to test the Exception that could be thrown in MyFinalClass and be caught in MyAbstractClass as the concrete method makes a call to the getObject method in MyFinalClass. 我正在使用Mockito服务来测试可能在MyFinalClass中引发并在MyAbstractClass中捕获的异常,因为具体方法在MyFinalClass中调用了getObject方法。
Please see below code. 请参见下面的代码。
public abstract class MyAbstractClass{
@Autowired
private MyFinalClass myFinalClass;
//concrete method
protected Object myConcreteMethod(String name){
try{
Object b = myFinalClass.getObject(name);
return b;
} catch(MyException e){
LOGGER.log("ERROR THROWN" + e);
}
}
}
public final class MyFinalClass {
public Object getObject(String name) throws MyException{
**** HAS NOT YET BEEN IMPLEMENTED ****
return null;
}
}
public MyException extends Exception{
....
}
Below is the test class I have written. 以下是我编写的测试课程。 Unfortunately I am having issues with Mockito.when(myFinalClass).getObject(name).thenReturn(Mockito.mock(Object.b)), as it does not seem to get called.
不幸的是,我遇到了Mockito.when(myFinalClass).getObject(name).thenReturn(Mockito.mock(Object.b))的问题,因为它似乎没有被调用。
@ContextConfiguration(locations = "classpath:applicationContext-test.xml")
@RunWith(PowerMockRunner.class)
public class MyAbstractClassTest {
public static class ExampleConcreteClass extends MyAbstractClass{
}
@InjectMocks
ExampleConcreteClass exampleConcreteClass;
@Mock
MyFinalClass myFinalClass;
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
}
@Test
public void testMyConcreteMethod(){
try{
Mockito.when(myFinalClass).getObject(name).
thenThrow(new MyException());
exampleConcreteClass.myConcreteMethod();
Assert.fail();
}catch(MyException e){
Assert.assertTrue(Boolean.TRUE);
}
}
}
Because the implementation has not yet been completed for the getObject(String name) method in MyFinalClass, I am throwing new MyException() on the call of the getObject method. 因为MyFinalClass中的getObject(String name)方法的实现尚未完成,所以我在getObject方法的调用上抛出了新的MyException()。 However the exception does not get thrown as the Mockito.when(...) call does not get called, causing Assertion to fail.
但是,由于未调用Mockito.when(...)调用,因此不会引发异常,从而导致断言失败。
Please help. 请帮忙。 Thank you.
谢谢。
Mockito is not able to mock out final classes. Mockito无法模拟最终课程。 There are a few ways to get around this.
有几种方法可以解决此问题。
1) In MyAbstractClass
consider not referencing a final class, and instead reference an interface or abstract class that MyFinalClass
implements (or extends). 1)在
MyAbstractClass
考虑不引用最终类,而应引用MyFinalClass
实现(或扩展)的接口或抽象类。 So lets say that MyFinalClass
implements an interface called MyGettableApi
. 因此,可以说
MyFinalClass
实现了一个名为MyGettableApi
的接口。 Then MyAbstractClass
would look like this. 然后
MyAbstractClass
看起来像这样。
public abstract class MyAbstractClass{
@Autowired
private MyGettableApi gettableService;
//concrete method
protected Object myConcreteMethod(String name){
try{
Object b = gettableService.getObject(name);
return b;
} catch(MyException e){
LOGGER.log("ERROR THROWN" + e);
}
}
}
public final class MyFinalClass implements MyGettableApi {
@Override
public Object getObject(String name) throws MyException{
**** HAS NOT YET BEEN IMPLEMENTED ****
return null;
}
}
public interface MyGettableApi {
public Object getObject(String name);
}
Now in your test code you can mock out MyGettableApi
, since it is not final, without a problem. 现在,在您的测试代码中,您可以模拟
MyGettableApi
,因为它不是最终的,没有问题。
@Mock
MyGettableApi myFinalClass;
2) Another way around this is wrap the call to myFinalClass.getObject(name);
2)解决此问题的另一种方法是包装对
myFinalClass.getObject(name);
的调用myFinalClass.getObject(name);
wrapped in another method. 包裹在另一种方法中。
public abstract class MyAbstractClass{
@Autowired
private MyFinalClass myFinalClass;
//concrete method
protected Object myConcreteMethod(String name){
try{
Object b = myGetObjectWrapperMethod(name);
return b;
} catch(MyException e){
LOGGER.log("ERROR THROWN" + e);
}
}
Object myGetObjectWrapperMethod(String name) {
return myFinalClass.getObject(name);
}
}
Now in your test code you would @Spy
the instance of MyAbstractClass
that is being tested. 现在,在您的测试代码中,您将
@Spy
正在测试的MyAbstractClass
实例。
@InjectMocks
@Spy
ExampleConcreteClass exampleConcreteClass;
then you can mock out our new wrapper method. 那么您可以模拟出我们的新包装方法。
doThrow(new MyException()).when(exampleConcreteClass).myGetObjectWrapperMethod(name);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.