gpt4 book ai didi

java - Mockito 依赖于先前调用的链接方法调用无法识别

转载 作者:行者123 更新时间:2023-12-01 20:15:21 25 4
gpt4 key购买 nike

我正在使用 Mockito 服务来测试可能在 MyFinalClass2 中引发并在 MyAbstractClass 中捕获的异常,因为具体方法会调用 MyFinalClass2 中的 getValue 方法。该方法返回一个接口(interface)(MyInterfaceClass)对象。

我之前在 Mocking Chained calls in Concrete Class Mockito 中问过一个问题值得庆幸的是,所提供的解决方案在调用 MyFinalClass 中的 getObject 方法时有效。因此,test1 有效!

但是,这次我有另一个最终类(MyFinalClass2),它不是 @Autowired,并且在调用 MyFinalClass 中的方法后调用。 MyFinalClass2 类型的对象从第一次调用 MyFinalClass 中的方法返回。当在 test2 中手动抛出 MyException2 时,它不会被识别,因此会在 Test2 中导致 AssertionFailure 。

另请注意,下面的代码行返回 NULL,因为它尚未实现。这就是为什么我在调用此方法时在 Test2 中返回 MyFinalClass2 的新实例的原因。

MyFinalClass2 myFinalClass2 = getObject(strName); 

请参阅下面的代码。

public abstract class MyAbstractClass{

@Autowired
private MyFinalClass myFinalClass;

//concrete method
protected MyInterfaceClass myConcreteMethod(String strName, String str)
{
try{
//returns null as it has not yet been implemented
MyFinalClass2 myFinalClass2 = getObject(strName);

MyInterfaceClass b = getValue(myFinalClass2,str);
return b;
} catch(MyException e){
LOGGER.log("ERROR THROWN" + e);
} catch(MyException2 e){
LOGGER.log("ERROR THROWN" + e);
}
}

public MyFinalClass2 getObject(String strName){
return myFinalClass.getObject(strName);
}

public MyInterfaceClass getValue(MyFinalClass2 myFinalClass2, String
str){
return myFinalClass2.getValue(str);
}

}
<小时/>
public final class MyFinalClass {

public MyFinalClass2 getObject(String strName) throws MyException{
**** HAS NOT YET BEEN IMPLEMENTED ****
return null;
}

}
<小时/>
public final class MyFinalClass2 {
public MyInterfaceClass getValue(String str) throws MyException2{
**** HAS NOT YET BEEN IMPLEMENTED ****
return null;
}
}
<小时/>
public interface MyInterfaceClass {
**** HAS NOT YET BEEN IMPLEMENTED BY ANY CLASS ****
void getStuff();
}
<小时/>
@ContextConfiguration(locations = "classpath:applicationContext-test.xml")
@RunWith(PowerMockRunner.class)
public class MyAbstractClassTest {

public static class ExampleConcreteClass extends MyAbstractClass{

}

@InjectMocks
@Spy
ExampleConcreteClass exampleConcreteClass;


@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
}

//THIS WORKS --- TEST 1
@Test
public void testIfExceptionOneIsThrown(){
try{
Mockito.when(exampleConcreteClass).getObject(name).
thenThrow(new MyException());

exampleConcreteClass.myConcreteMethod();
Assert.fail();
}catch(MyException e){
Assert.assertTrue(Boolean.TRUE);
}
}

//This test DOES NOT work --- TEST 2
@Test
public void testIfExceptionTwoIsThrown(){
try{
MyFinalClass2 myFinClass2 = new MyFinalClass2();
String strName = "name";
String str = "str";
Mockito.when(exampleConcreteClass).getValue(myFinClass2,str).
thenThrow(new MyException2());

Mockito.when(exampleConcreteClass).getObject(strName).
thenReturn(myFinClass2);

exampleConcreteClass.myConcreteMethod();
Assert.fail();
}catch(MyException e){
Assert.fail();
}catch(MyException2 e){
Assert.assertTrue(Boolean.TRUE);
}
}

}

请帮忙。非常感谢!

最佳答案

首先,我很抱歉这么说,但是如果您需要认真思考测试,那么通常就表明代码很糟糕。不管怎样,你不需要 PowerMock,因为 Mockito 2 能够 mock final classes已经(不过你必须选择加入)。

此外,您的测试根本没有任何意义,因为您的 exampleConcreteClass.myConcreteMethod() 无法抛出 MyException2,因为...

    } catch(MyException2 e){
LOGGER.log("ERROR THROWN" + e);
}

...因此 MyException2 永远不会离开该方法的范围,而是会在那里转换为日志消息,然后被丢弃。它不会离开该方法,因此尝试断言它不会起作用。你也会有类似 throw e; 的东西:

    } catch(MyException2 e){
LOGGER.log("ERROR THROWN" + e);
throw e; // re-throw e, otherwise it ends here
}

另外,作为一个提示,您想要做的事情可以通过简单的书写更轻松地完成...

@Test(expected=MyException2.class)
public void testIfExceptionTwoIsThrown() throws MyException, MyException2 {

...这样,您就可以从测试方法中删除所有 try-catch 内容,因为如果没有抛出 MyException2,JUnit 将自动使测试失败。或者,如果您想拥有更多控制权,您甚至可以查看 JUnit 的 ExpectedException规则,它比 expected 参数更强大、更通用(但对于本例来说,这个应该足够了)。

但是,当然,没有什么改变这样的事实:只要你的方法捕获了 MyException2,它就不会留下所述方法,因此测试它不会有帮助。

关于java - Mockito 依赖于先前调用的链接方法调用无法识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45898667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com