我认为,依赖项注入的主要好处之一是可以将模拟和/或存根对象注入代码中,以提高可测试性,增加测试覆盖率并编写更好,更有意义的测试。 但是,有时候您会遇到一些不使用依赖注入的传统代码,而是通过组合而不是聚合将它们结合在一起。

发生这种情况时,您有三种选择:

  1. 忽略该问题,不编写任何测试。
  2. 疯狂地进行重构,更改所有内容以使用依赖项注入。
  3. 使用PowerMock模拟构造函数

显然,选项1并不是一个严肃的选项,尽管我建议重构以将所有内容移至依赖项注入,但这需要时间,而且您必须务实。 这就是PowerMock的用处。此博客演示了如何使用PowerMock模拟构造函数,这意味着当您的代码调用new时,它不会创建真实的对象,而是会创建模拟对象。

为了证明这个想法,我们首先需要测试一些类,如下所示。

public class AnyOldClass {public String someMethod() {return "someMethod";}}
public class UsesNewToInstantiateClass {public String createThing() {AnyOldClass myclass = new AnyOldClass();String returnValue = myclass.someMethod();return returnValue;}}

第一个类AnyOldClass是代码通过调用new实例化的类。 在这个例子中,顾名思义,它可以是任何东西。

第二个类,恰当地命名为UsesNewToInstantiateClass,具有一个方法createThing(),该方法在调用时会执行以下操作:

AnyOldClass myclass = new AnyOldClass();

这一切都非常简单,因此我们将快速进行PowerMock辅助的JUnit测试:

import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.replay;
import static org.powermock.api.easymock.PowerMock.verify;import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.annotation.Mock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;@RunWith(PowerMockRunner.class)
@PrepareForTest(UsesNewToInstantiateClass.class)
public class MockConstructorTest {@Mockprivate AnyOldClass anyClass;private UsesNewToInstantiateClass instance;@Testpublic final void testMockConstructor() throws Exception {instance = new UsesNewToInstantiateClass();expectNew(AnyOldClass.class).andReturn(anyClass);final String expected = "MY_OTHER_RESULT";expect(anyClass.someMethod()).andReturn(expected);replay(AnyOldClass.class, anyClass);String result = instance.createThing();verify(AnyOldClass.class, anyClass);assertEquals(expected, result);}}

首先,该类具有通常的PowerMock附加功能:

@RunWith(PowerMockRunner.class)
@PrepareForTest(UsesNewToInstantiateClass.class)

在文件的顶部加上anyOldClass模拟对象的创建。 要考虑的重要代码行是:

expectNew(AnyOldClass.class).andReturn(anyClass);

这行代码告诉PowerMock期望调用新的AnyOldClass()并返回我们的anyClass模拟对象。

同样有趣的是重播和验证的调用。 在上面的示例中,它们都有两个参数。 第一个,AnyOldClass.class与上面的ExpectNew(…)调用有关,而第二个,anyClass则与简单的模拟调用Expect(anyClass.someMethod())。Return(expected);相关。

在某些时候,您确实应该让new来做它所做的事情:创建一个请求类型的新对象。 有一种观点认为,在测试时您可能过度隔离代码,而对所有内容进行模拟会降低测试的含义和价值。 对我来说,没有正确的答案,这是一个选择的问题。

很明显,如果您的代码访问诸如数据库之类的外部资源,那么您将重构并实现DI或使用PowerMock。 如果您的被测试代码不访问任何外部资源,那么更多的是判断多少代码隔离过多? 这也许需要一些思考,并且可能是另一天另一个博客的主题……

参考: 使用PowerMock从我们的JCG合作伙伴 Roger Hughes 嘲笑 “ Captain Debug's”博客中的 构造方法 。

翻译自: https://www.javacodegeeks.com/2012/09/using-powermock-to-mock-constructors.html

使用PowerMock模拟构造函数相关推荐

  1. powermock模拟对象_使用PowerMock模拟构造函数

    powermock模拟对象 在我看来,依赖注入的主要好处之一是可以将模拟和/或存根对象注入代码中,以提高可测试性,增加测试覆盖率并编写更好,更有意义的测试. 但是,有时候您会遇到一些不使用依赖注入的传 ...

  2. powermock模拟对象_使用PowerMock测试对象的内部状态

    powermock模拟对象 大多数单元测试都集中于测试对象的行为以证明其有效. 这可以通过编写一个JUnit测试来实现,该测试调用对象的公共方法,然后测试这些调用的返回值是否与先前定义的一组期望值匹配 ...

  3. 使用PowerMock模拟静态方法

    在最近的博客中,我试图强调使用依赖注入的好处,并表达一种想法,即这种技术的主要好处之一是,通过在类之间提供高度的隔离,它可以使您更轻松地测试代码,并且得出的结论是,许多好的测试等于好的代码. 但是,当 ...

  4. Easymock和Powermock

    Easymock Mock对象用于在单元测试中模拟一些难以构造或者比较复杂的对象,从而把测试环境和外界环境隔开,easymock默认只支持模拟接口对象 1. 引入Easymock的jar包 <d ...

  5. mockito 静态方法_Mockito模拟静态方法– PowerMock

    mockito 静态方法 Mockito allows us to create mock objects. Since static method belongs to the class, the ...

  6. PowerMock 简介--转载

    原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-powermock/ EasyMock 以及 Mockito 都因为可以极大地简化单元测试的书 ...

  7. PowerMock 入门

    文章目录 介绍 Mock测试 好处-- 模拟数据 好处--减少依赖 包导入 示例 常用注解 @RunWith(PowerMockRunner.class) @PrepareForTest({UserC ...

  8. PowerMock 简介

    EasyMock 以及 Mockito 都因为可以极大地简化单元测试的书写过程而被许多人应用在自己的工作中,但是这 2 种 Mock 工具都不可以实现对静态函数.构造函数.私有函数.Final 函数以 ...

  9. 玩转Spring JUnit+mockito+powermock单元测试(使用详解)

    说明:请耐心看完... Spring中执行单元测试,最麻烦的就是解决Bean的定义以及注入的问题.最开始使用Spring的上下文初始化进行测试,开头是这样的: @RunWith(SpringJUnit ...

最新文章

  1. C++中STL中的大、小、相等概念
  2. 设计模式之一:单例模式(Singleton Pattern)
  3. Qt/E中的键盘设备管理
  4. 开启php,php开启openssl的方法
  5. 跨国婚姻登记指南是怎样的一个流程呢??
  6. IDEA出现错误:找不到或无法加载主类 io.renren.RenrenApplication
  7. 面试题—Redis篇
  8. java的character用法_Java中Character类的使用方法
  9. HDU 1856 Brave Game(巴什博奕)
  10. 计算机课计划,计算机教学计划汇总
  11. Python标准库-string模块《未完待续》
  12. PAT乙级 1033 旧键盘打字 (20 分)
  13. docker pull命令入门
  14. 同一进程不同线程之间的资源共享与独享
  15. 电赛练习之旋转倒立摆
  16. c语言程序设计的反思,C语言程序设计教学反思
  17. 获取棋盘格与标准模板在扫描仪上不同位置图片
  18. ionic ionc-item去掉下划线
  19. 编写TaskMgr.exe的时候学习的知识点
  20. greenplum,teradata,presto,clickhouse四种分布式数据库的对比

热门文章

  1. pandas追加写入excel_[Excel]如果你爱Excel,请学好pandas
  2. java泛型——桥方法
  3. Hibernate关联关系配置(一对多、一对一和多对多)
  4. java中的可检查和不检查_检查Java测试中发生了什么
  5. java客户端api文档_Java 11:新的HTTP客户端API
  6. java 谓词_谓词::不适合Java
  7. 用xshell传输jdk_在JDK 9中将InputStream传输到OutputStream
  8. 忽略异常_忽略已检查的异常,所有出色的开发人员都在这样做–基于600,000个Java项目...
  9. java名 java_Java Syncrhonisers
  10. junit5和junit4_JUnit 5 –下一代JUnit的初步了解