如果要编写轻量级的JUnit测试, Mockito是我最喜欢的小帮手。 如有必要,可以通过模拟轻松地替换被测单元的“实际”依赖关系,这非常有用。 尤其是在处理框架API的边界线时,此类依赖项的设置否则可能非常昂贵。
但是有时候情况要复杂一些。 例如,如果测试出于某种原因需要与至少一个属于这种框架的真实实例进行交互。 如果此交互包括将模拟作为参数传递给此实例,那么很幸运,实现会将参数强制转换为从交互器的角度来看未知的类型。
这是一个简单的例子来澄清这一点:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26public interface Foo { [...] } public class Bar { public Bar( Foo foo ) { Runnable runnable = ( Runnable )foo; runnable.run(); } [...] } public class SomeTest { @Test public void testConstructor() { Foo fooMock = mock( Foo.class ); // fails with ClassCastException Bar bar = new Bar( fooMock ); [...] } }
可以将Bar
类视为需要某种实现的框架代码。 由于参数类型Foo
不能反映这种期望,因此将Foo
模拟传递给Bar
的构造函数将导致测试失败,并带有ClassCastException
。
也许您在想到上述情况时首先想到的是,框架通过强制转换为未声明的类型而变得很糟,并且最好将所有内容扔掉并重新开始,从而更好!
不幸的是,在现实世界中,这种行为可以说是有效的。 例如, Eclipse平台具有许多被声明为“不打算由客户端实现”的接口。 一个很好的例子就是团队API的IHistoryView
接口。 可以肯定地使用3.x平台,尽管IHistoryView
实现扩展了IViewPart
,但是历史视图界面并未公开这一细节。
在这种情况下,有时可能需要创建多种类型的模拟-一种实现IHistoryView
和IViewPart
的模拟-尽管API并未指出所有这些。 Mockito通过鲜为人知的MockSettings#extraInterfaces
模拟配置功能简化了此过程。 以下代码段显示了如何使用extraInterfaces
修复上述示例的测试。
1
2
3
4
5
6
7
8
9
10@Test public void testConstructor() { Foo mock = mock( Foo.class, withSettings().extraInterfaces( Runnable.class ) ); // the mock now supports the cast to runnable Bar bar = new Bar( mock ); [...] }
使用withSettings
的方法调用会创建一个新的MockSettings
实例,并使用其他Runnable
类型MockSettings
进行配置。 生成的Foo
模拟实例同时实现Foo
和Runnable
。 现在测试通过了。
但是请记住,尽管在这篇文章中使用额外接口的动机似乎是合理的,但要强调的是,在实际使用此功能之前,您应该三思而后行。 或者如文档所述,“如果您碰巧经常使用它,请确保您确实在编写简单,干净且可读的代码。” 粗心地使用它绝对是一个预定的突破点。
翻译自: https://www.javacodegeeks.com/2014/03/what-are-mockito-extra-interfaces.html
最后
以上就是淡然柠檬最近收集整理的关于什么是Mockito Extra接口?的全部内容,更多相关什么是Mockito内容请搜索靠谱客的其他文章。
发表评论 取消回复