当前位置: 首页 > 知识库问答 >
问题:

无法识别依赖于前一个调用的Mockito链接方法调用

申屠裕
2023-03-14

我之前在模拟具体类Mockito中的链接调用时问了一个问题,幸运的是,提供的解决方案在调用MyFinalClass中的getObject方法时起作用。因此,test1起作用了!

但是,这一次我有另一个最终类(MyFinalClass2),它不是@AutoWired,是在调用MyFinalClass中的方法之后调用的。MyFinalClass中的方法的第一次调用返回MyFinalClass2类型的对象。当在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);
        }
   }

}

请帮帮忙。大加赞赏!

共有1个答案

马琛
2023-03-14

首先,我很抱歉这样说,但是如果您需要对测试进行如此认真的思考,那么这通常是代码糟糕的一个肯定迹象。当然,您不需要PowerMock,因为Mockito2已经能够模拟最终类了(不过,您必须选择加入)。

您的测试也没有任何意义,因为您的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,它就不会离开所述方法,因此对它进行测试将无济于事。

 类似资料:
  • uniapp 链接手机调试,无法识别手机? 打开了usb 调试模式,把手机查到同事电脑上可以识别,本电脑之前也可以,但是重装系统后就不行了,请问如何解决?

  • 我有一个类,它有两个方法。我想模拟这个类,然后模拟第一个方法,但不是第二个。 例如。 单元测试代码: 奇怪的是m2没有被调用。 我错过什么了吗?

  • null 附注:Maven-Build是成功的。因此,Maven正在识别存储库中的包。

  • 我想创建一个.xlsx工作簿。按照教程中的说明和其他Stackoverflow问题(如以下所示) 无法在Apache POI中导入XSSF

  • 我是Gradle的新手,我正在尝试这个教程https://spring.io/guides/gs/rest-service/我能够编译具有所需依赖项的jar并运行它。然而,IDE无法识别这些库,这让我很恼火。 有没有办法呢?

  • 给定类别FOO: 我尝试使用JDK8而不是9,它工作得很好。我不知道它为什么会失败,也不知道我怎么才能让它成功。 当是依赖项时,就会发生此问题。如果您为其他类型(如)更改它,它可以正常工作...