■前言
今天修改完代码之后,修改对应的Junit。
对于目前这个工程,之前有一次案件对于,在整个工程中,使用Junit4 + JMockit方式,来实现Junit。
之前修改的测试类,都是通过以下方式实现的
XXXXXTest extends DJunitTestCase
而我修改的代码,之前的担当者,漏了修改了。
--------------------------
于是我修改代码如下 (粉色部分是我修改的)
@RunWith(JMockit.class)
XXXXXTest extends TestCase{
@Test
public void XXXTest() {。。。}
。。。。
}
修改之后,就出现了标题中描述的内容
Eclipse中 Junit 正常运行完了 可是方法覆盖率全红
--------------------------
■问题原因
Eclipse的EclEmma插件使用时,做了【除外:Excludes】的处理
比如,下面的位置,填写「com.sxz.demo.*」
那么,这个包下面所有的类,对应的Junit执行时,都不会统计覆盖率。
测试代码执行后,即使正常完了,每行代码都是红色,而不是期待的绿色。
(设置的目的:为了解决 类子的属性多出了一个 $jacocoData
本文最下面,■相关知识2 中详细说明)
■问题原因推测(推测错误),但是内容是正确的
1.@Test注解与继承TestCase混用
---------------------------------
继承TestCase:Junit3的方式,方法名以test为前缀, 方法名以test为前缀 , 方法名以test为前缀!!
@Test注解:Junit4的方式,方法上使用注解@Test
---------------------------------
2.继承 TestCase时,所有的标注(Annotation)失效
---------------------------------
所有方法,没有以test为前缀,@Test又失效了,
因此,该方法虽然正常执行了,但是么有被统计!!!
追记,今天看了代码,方法是以testXXX这种形式存在的。
---------------------------------
3.扩展
@BeforeClass和@AfterClass是JUnit4得新特性,
标记有@BeforeClass的方法会载所有的测试方法执行开始前运行,
标记有@AfterClass的方法会在所有的测试方法运行结束后执行。
4.继承关系
TestCase继承了Assert
可以直接使用Assert中定义的镜头方法,简化代码
-----------------------------------
■相关知识1
1.Maven引用
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.21</version>
</dependency>
2.Eclipse中,Junit执行后,代码覆盖率相关的插件:EclEmma
3.代码相关
import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.Tested;
import mockit.Verifications;
import mockit.integration.junit4.JMockit;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(JMockit.class)
public class HelloDemoTest {
/**
* mock公有方法
*/
@Test
public void testPublicMethod() {
final HelloDemo hello= new HelloDemo ();
// 设定期待值
new Expectations(hello) {
{
hello.getAnything();
result = 100;
times = 1;
}
};
// 断言
Assert.assertEquals(100, hello.getAnything());
// 方法执行次数
new Verifications() {
{
hello.getAnything();
times = 1;
}
};
}
}
如果继承Assert,上面的断言就可以直接写了,不需要前面的类
4.关于反射
问: 为什么我们会在Junit代码中,会经常看到反射的使用。
回答:我们可以通过反射,调用类的私有方法
https://blog.csdn.net/fy_java1995/article/details/80088733
https://blog.csdn.net/yizhenn/article/details/52384582
5.DJunit 与 Eclipse 中的EclEmma 插件
貌似使用这个插件,无法统计出来Djunit写的代码的覆盖率,
所有,后来换成Junit4
6.Junit4 + JMockit
https://blog.csdn.net/yizhenn/article/details/52384582
===
Mockito和JMockit
(JMockit、EasyMock、Mockito和PowerMock)
https://www.jb51.cc/java/122225.html
===
7.反射相关的代码
7.0 获取Class对象的三种方法
- Class.forName(“类的全限定名”) // 下面我们将使用这一种
- 实例对象.getClass()
- 类名.class (类字面常量)
7.1 调用构造函数创建类
// 反射的类,自定义了构造函数,构造函数中,只有一个String参数
// 每一个类都默认有一个无参的构造函数,但是但我们自己定义后,默认的无参的构造函数便消失了
// 如果父类是抽象类,继承父类,要实现父类的构造方法
// 也就是说,在自定义的构造方法的第一行,要写上supper();
Constructor<?> con = clazz.getDeclaredConstructor(String.class);
Object obj = con.newInstance("testName");
7.2调用方法
Class clazz = Class.forName("Student");
Constructor<?> con = clazz.getConstructor(String.class, int.class);
Student student = (Student) con.newInstance("MyName", 18);
Method method=clazz.getMethod("myMethod", String.class);
method.invoke(student, "gogogo");
上面的代码中,Student有一个两个参数的构造方法,和一个名字为「myMethod」的方法(此方法有一个String类型的参数)
https://blog.csdn.net/fy_java1995/article/details/80088733
7.3 构造方法反射时的区别
・getDeclaredConstructor(Class<?>... parameterTypes)
这个方法会返回制定参数类型的所有构造函数,包括public的和非public的,当然也包括private
・getDeclaredConstructors()
返回结果就没有参数类型的过滤,返回的是一个数组
・getConstructor(Class<?>... parameterTypes)
这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造函数
----
■相关知识2 :EclEmma插件安装方法
8.Eclipse插件安装方法(非常简单)
8.1 Help -->Eclipse Marketplace
8.2 输入插件名字「EclEmma」然后回车,点击按照即可
■相关知识3(一般代码不会遇到这个坑)
使用覆盖率的方式执行测试代码时,类中会多出下面这个属性
$jacocoData(Java Code Coverage)
所有如果,使用反射取得类的属性(Fileds)时,会多取出来一个属性。
今天就遇到了这个问题,
正常执行Junit代码时,可以正常完了,
而是用覆盖率执行时,代码里面直接报错,说类的属性(Fields)的个数不正确。
因为,测试对象代码里面,取得了类的属性的个数进行判断,当不正确时,抛出异常
比如这个类里面有两个属性,正常执行时,取得的属性就是2个,所有没有问题;
而当使用覆盖率方式执行代码时,取得的属性个数是3个,不正确,抛出异常!
解决方法,把这个类,设置为覆盖率统计对象外,
这样,在Junit执行时,这个类便不会多出一个$jacocoData 属性来。
-----
■相关知识4 :覆盖率抽出与合并
■カバレッジ抽出(覆盖率抽出与合并)
https://www.cnblogs.com/Echo-41/p/6922993.html
(使用 Junit4 + JMockit ),按照下面步骤,可以到处覆盖率的文件
Java -> Coverage Report -> Next -> 选择导出格式(推荐HTML)-> 选择导出目录 -> Finished
(导出前,如果执行多次,可以合并多次执行后的覆盖率)
--------
step1
step2 (现在虽然安装了插件,但是没有使用Junit4,也许是因为这个原因,自己的电脑的Eclipse中看不到,
但是,在单位的开发环境中是可以看到的。)
--
自己的电脑的效果如下(感觉和Junit4没有什么关系,应该是插件版本和Eclipse版本的问题)
-----