栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java 初始化模拟对象-MockIto

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 初始化模拟对象-MockIto

对于模拟初始化,使用

Runner
或是
MockitoAnnotations.initMocks
严格等效的解决方案。从MockitoJUnitRunner的javadoc中:

JUnit 4.5 runner initializes mocks annotated with Mock, so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary. Mocks are initialized before each test method.

MockitoAnnotations.initMocks
当你已经
SpringJUnit4ClassRunner
在测试用例上配置了特定的运行器时,可以使用第一个解决方案(带有)。

第二个解决方案(带有

MockitoJUnitRunner
)更经典,也是我的最爱。代码更简单。使用转轮提供了很大的优势框架使用的自动验证。

两种解决方案都可以在测试方法之间共享模拟(和间谍)。与结合使用@InjectMocks,它们可以非常快速地编写单元测试。样板代码减少了,测试更易于阅读。例如:

@RunWith(MockitoJUnitRunner.class)public class ArticleManagerTest {    @Mock private ArticleCalculator calculator;    @Mock(name = "database") private ArticleDatabase dbMock;    @Spy private UserProvider userProvider = new ConsumerUserProvider();    @InjectMocks private ArticleManager manager;    @Test public void shouldDoSomething() {        manager.initiateArticle();        verify(database).addListener(any(ArticleListener.class));    }    @Test public void shouldDoSomethingElse() {        manager.finishArticle();        verify(database).removeListener(any(ArticleListener.class));    }}

优点:代码很少

缺点:黑魔法。IMO这主要是由于@InjectMocks注释。有了这个注释, “你可以放松代码的痛苦”(请参阅@Brice的精彩评论)

第三种解决方案是在每个测试方法上创建模拟。正如@mlk在其答案中所解释的,它允许进行“ 自包含测试 ”。

public class ArticleManagerTest {    @Test public void shouldDoSomething() {        // given        ArticleCalculator calculator = mock(ArticleCalculator.class);        ArticleDatabase database = mock(ArticleDatabase.class);        UserProvider userProvider = spy(new ConsumerUserProvider());        ArticleManager manager = new ArticleManager(calculator,         userProvider,         database);        // when         manager.initiateArticle();        // then         verify(database).addListener(any(ArticleListener.class));    }    @Test public void shouldDoSomethingElse() {        // given        ArticleCalculator calculator = mock(ArticleCalculator.class);        ArticleDatabase database = mock(ArticleDatabase.class);        UserProvider userProvider = spy(new ConsumerUserProvider());        ArticleManager manager = new ArticleManager(calculator,         userProvider,         database);        // when         manager.finishArticle();        // then        verify(database).removeListener(any(ArticleListener.class));    }}

优点:你可以清楚地演示api的工作原理(BDD …)

缺点:还有更多样板代码。(模拟创作)

我的建议是妥协。将

@Mock
注释与一起使用
@RunWith(MockitoJUnitRunner.class)
,但不要使用
@InjectMocks

@RunWith(MockitoJUnitRunner.class)public class ArticleManagerTest {    @Mock private ArticleCalculator calculator;    @Mock private ArticleDatabase database;    @Spy private UserProvider userProvider = new ConsumerUserProvider();    @Test public void shouldDoSomething() {        // given        ArticleManager manager = new ArticleManager(calculator,         userProvider,         database);        // when         manager.initiateArticle();        // then         verify(database).addListener(any(ArticleListener.class));    }    @Test public void shouldDoSomethingElse() {        // given        ArticleManager manager = new ArticleManager(calculator,         userProvider,         database);        // when         manager.finishArticle();        // then         verify(database).removeListener(any(ArticleListener.class));    }}

优点:你可以清楚地演示api的工作原理(如何ArticleManager实例化my )。没有样板代码。

缺点:测试不是独立的,代码痛苦更少



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/456629.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号