不能使用Mockito抛出异常

时间:2014-09-25 12:22:01

标签: java android testing mockito stubs

当方法运行时,我想抛出一个异常(在测试时)。 我可以做几件事:

  
      
  1. stub(mock.someMethod(“some arg”))。toThrow(new RuntimeException());
  2.   
  3. when(mock.someMethod(“some arg”))。thenThrow(new runtimeException())
  4.   
  5. doThrow .....
  6.   

通常我会创建一个间谍对象来调用spied方法。使用存根我可以抛出异常。始终在日志中监视此异常。更重要的是,测试不会崩溃,因为抛出异常的方法可以捕获它并返回特定值。但是,在代码中,不会抛出异常(在日志和监视器中没有监视任何内容,并且返回值为true但应该为false)。

问题:在这种情况下,不会抛出异常:

    DeviceInfoHolder deviceInfoHolder = new DeviceInfoHolder();

    /*Create Dummy*/

    DeviceInfoHolder mockDeviceInfoHolder = mock (DeviceInfoHolder.class);

    DeviceInfoHolderPopulator deviceInfoHolderPopulator  = new DeviceInfoHolderPopulator(); 

    /*Set Dummy */
    deviceInfoHolderPopulator.setDeviceInfoHolder(mockDeviceInfoHolder);

    /*Create spy */
    DeviceInfoHolderPopulator spyDeviceInfoHolderPopulator = spy(deviceInfoHolderPopulator);

    /*Just exception*/
    IllegalArgumentException toThrow = new IllegalArgumentException();

    /*Stubbing here*/
    stub(spyDeviceInfoHolderPopulator.populateDeviceInfoHolder()).toThrow(toThrow);

    /*!!!!!!Should be thrown an exception but it is not!!!!!!*/
    boolean returned = spyDeviceInfoHolderPopulator.populateDeviceInfoHolder();
    Log.v(tag,"Returned : "+returned);

3 个答案:

答案 0 :(得分:1)

间谍的语法略有不同:

doThrow(toThrow).when(spyDeviceInfoHolderPopulator).populateDeviceInfoHolder();

阅读“窥探真实物体的重要问题”部分。在这里:https://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#13

答案 1 :(得分:1)

创建新答案,因为spyDeviceInfoHolderPopulator.populateDeviceInfoHolder();是你的测试方法。

单元测试的基本规则之一是你不应该测试方法,因为你想测试它的行为。您可能希望使用Mockito存储测试类的伪造依赖项的方法。

所以在这种情况下,您可能想要删除间谍,调用您的测试方法并作为测试的最后阶段(当前缺失),您应该验证测试方法中的逻辑是否正确。

编辑:

在最后一次评论之后,我终于清楚你正在测试什么逻辑。 假设您的测试对象依赖于某些XmlReader。同样想象一下,这个读者有一种名为" readXml()"并在您的测试逻辑中用于从XML读取。我的测试看起来像这样:

XmlReader xmlReader = mock (XmlReader.class);
mock(xmlReader.readXml()).doThrow(new IllegalArgumentException());

DeviceInfoHolderPopulator deviceInfoHolderPopulator  = new DeviceInfoHolderPopulator(xmlReader); 

//call testing method
boolean returned = spyDeviceInfoHolderPopulator.populateDeviceInfoHolder();

Assign.assignFalse(returned);

答案 2 :(得分:0)

这里间谍对象的创建很糟糕。

创作应该像

DeviceInfoHolderPopulator spyDeviceInfoHolderPopulator = spy(new DeviceInfoHolderPopulator());

然后在间谍对象上存根你的方法。

参考:API

编辑:

这是来自API。

Sometimes it's impossible or impractical to use Mockito.when(Object) for stubbing spies. 
Therefore for spies it is recommended to always 
use doReturn|Answer|Throw()|CallRealMethod family of methods for stubbing. 
Example:

List list = new LinkedList();
List spy = spy(list);

//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");

//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);