问题描述

最近在写一些单元测试用例,为了避免连接外界服务,所有选择mock了数据库Dao层,计划将数据库所需要的数据存在List中,在类加载的时候初始化List并且填充数据。代码如下:

 public class UserDaoMock extends UserDao {
@Override
public List<UserInfo> selectUserInfo() {
return getUserInfo();
} static {
initUserInfo();
} public static UserInfo getUserInfo() {
return userInfos;
} private static List<UserInfo> userInfos = new ArrayList<UserInfo>();
private static void initUserInfo() {
UserInfo userInfo1 = new UserInfo();
userInfo1.setId(1L);
userInfo1.setPin("user1");
userInfo1.setUserId(1L);
userInfo1.setDataBillingType(1);
userInfo1.setErp("operator1");
userInfo1.setCreatedTime("2019-01-01");
userInfo1.setModifiedTime("2019-05-01");
userInfo1.setYn(1);
userInfos.add(userInfo1); UserInfo userInfo2 = new UserInfo();
userInfo2.setId(2L);
userInfo2.setPin("user2");
userInfo2.setUserId(2L);
userInfo2.setDataBillingType(1);
userInfo2.setErp("operator2");
userInfo2.setCreatedTime("2019-01-01");
userInfo2.setModifiedTime("2019-05-01");
userInfo2.setYn(1);
userInfos.add(userInfo2); UserInfo userInfo3 = new UserInfo();
userInfo3.setId(3L);
userInfo3.setPin("user3");
userInfo3.setUserId(3L);
userInfo3.setDataBillingType(1);
userInfo3.setErp("operator1");
userInfo3.setCreatedTime("2019-01-01");
userInfo3.setModifiedTime("2019-05-01");
userInfo3.setYn(1);
userInfos.add(userInfo3);
}
}

结果在new对象的时候:

 UserDao userDao = new UserDaoMock();

一直报错:

java.lang.ExceptionInInitializerError
at com.jd.ads.afa_index.indexes.task.TestUserServiceTask.setUp(TestUserServiceTask.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:119)

起初以为是init方法出错了,尝试了多种方式,才发下原来是类加载时,当执行到static{}语句块时开始调用userInfos,但userInfos这个list由于是在后面而还未定义和初始化,所以导致了错误。还是因为基础知识不扎实啊!!!

问题解决

将static对象提到最前面,即解决了此问题,简直愚昧的我啊:

 public class UserDaoMock extends UserDao {
private static List<UserInfo> userInfos = new ArrayList<UserInfo>(); @Override
public List<UserInfo> selectUserInfo() {
return getUserInfo();
} static {
initUserInfo();
} public static UserInfo getUserInfo() {
return userInfos;
} private static void initUserInfo() {
UserInfo userInfo1 = new UserInfo();
userInfo1.setId(1L);
userInfo1.setPin("user1");
userInfo1.setUserId(1L);
userInfo1.setDataBillingType(1);
userInfo1.setErp("operator1");
userInfo1.setCreatedTime("2019-01-01");
userInfo1.setModifiedTime("2019-05-01");
userInfo1.setYn(1);
userInfos.add(userInfo1); UserInfo userInfo2 = new UserInfo();
userInfo2.setId(2L);
userInfo2.setPin("user2");
userInfo2.setUserId(2L);
userInfo2.setDataBillingType(1);
userInfo2.setErp("operator2");
userInfo2.setCreatedTime("2019-01-01");
userInfo2.setModifiedTime("2019-05-01");
userInfo2.setYn(1);
userInfos.add(userInfo2); UserInfo userInfo3 = new UserInfo();
userInfo3.setId(3L);
userInfo3.setPin("user3");
userInfo3.setUserId(3L);
userInfo3.setDataBillingType(1);
userInfo3.setErp("operator1");
userInfo3.setCreatedTime("2019-01-01");
userInfo3.setModifiedTime("2019-05-01");
userInfo3.setYn(1);
userInfos.add(userInfo3);
}
}

注:

类加载时不会为实例变量赋值,对象创建时不会为静态变量赋值。我们调用静态方法时,此类就开始加载,加载的时候不会为实例变量赋值,但是会按顺序给静态变量赋值。

类加载特性 :
      *在虚拟机的生命周期中一个类只被加载一次。
      *类加载的原则:延迟加载,能少加载就少加载,因为虚拟机的空间是有限的。
      *类加载的时机:
      1)第一次创建对象要加载类.
      2)调用静态方法时要加载类,访问静态属性时会加载类。
      3)加载子类时必定会先加载父类。
      4)创建对象引用不加载类.
      5) 子类调用父类的静态方法时
          (1)当子类没有覆盖父类的静态方法时,只加载父类,不加载子类
          (2)当子类有覆盖父类的静态方法时,既加载父类,又加载子类
      6)访问静态常量,如果编译器可以计算出常量的值,则不会加载类,例如:public static final int a =123;否则会加载类,例如:public static final int a = math.PI。

转载请注明:https://www.cnblogs.com/fnlingnzb-learner/p/10615516.html

最新文章

  1. postgresql function 返回 select
  2. fis自动化部署
  3. mysql 自连接
  4. centos7配置mono和jexus5.6.2
  5. Oracle外部表的使用
  6. 【BZOJ1500】[NOI2005]维修数列
  7. BZOJ 1560 火星藏宝图(DP)
  8. Flot chart学习笔记
  9. python文本文件,生成指定的文件格式
  10. 【C基础】const用法
  11. 22 Notification 通知栏代码
  12. Luogu P2056 [ZJOI2007]捉迷藏
  13. linux driver ------ GPIO的驱动编写和调用
  14. springcloud-1: 用官方的pom.xml配置添加依赖失败
  15. Caffarelli 关于自由边界正则性的论文C1
  16. git 命令(补充篇)的本质理解
  17. quartz定时任务及时间设置
  18. linux下常用文件传输命令(转)
  19. Mybatis的多对多映射
  20. SharePoint 2013创建应用程序时IIS端口文件夹下没文件

热门文章

  1. UML类图之间的关系
  2. 链表用途&amp;&amp;数组效率&amp;&amp;链表效率&amp;&amp;链表优缺点
  3. 模拟赛T1 素数
  4. NOIP练习赛题目6
  5. [CQOI2009]跳舞
  6. Centos部署使用Jexus承载asp.net core2 web应用
  7. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) E. Tree Folding 拓扑排序
  8. Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem I. Alien Rectangles 数学
  9. USBDM BDM Interface for Freescale Microcontroller -- Hardware
  10. ubuntu下msmtp+mutt的安装和配置