2

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

  1. stub(mock.someMethod("some arg")).toThrow(new RuntimeException());
  2. when(mock.someMethod("some arg")).thenThrow(new RuntimeException())
  3. 投掷……

通常我会创建一个 spy 对象来调用 spy 方法。使用存根我可以抛出异常。此异常始终在日志中进行监控。更重要的是测试不会崩溃,因为抛出异常的方法可以捕获它并返回特定的值。但是,在下面的代码中没有抛出异常(在日志中没有监控任何内容 && 返回值为真但应该为假)。

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

    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);
4

3 回答 3

1

spy 的语法略有不同:

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

在“间谍真实对象的重要问题”部分阅读更多内容!在这里:https ://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#13

于 2014-09-25T12:29:26.670 回答
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);
于 2014-09-25T13:13:19.177 回答
0

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

创作应该是这样的

DeviceInfoHolderPopulator spyDeviceInfoHolderPopulator = spy(new DeviceInfoHolderPopulator());

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

参考: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);
于 2014-09-25T12:27:43.730 回答