当方法正在运行时,我想抛出一个异常(在测试时)。我能做的事情很少:
- stub(mock.someMethod("some arg")).toThrow(new RuntimeException())
- when(mock.someMethod("some arg")).thenThrow(new RuntimeException())
- doThrow
通常我会创建一个间谍对象来调用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);
创建新答案,因为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);
间谍的语法略有不同:
doThrow(toThrow).when(spyDeviceInfoHolderPopulator).populateDeviceInfoHolder();
点击此处阅读"监视真实物体的重要发现!"部分的更多信息:https://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#13
这里间谍对象的创建很糟糕。
创建应该像一样
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);