测试代码

  1. package org.simonme.srcstudy.spring3.demo.stub;
  2. import static org.junit.Assert.assertNotNull;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.simonme.srcstudy.spring3.demo.service.UserService;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9. /**
  10. * <一句话功能简述>
  11. * <功能详细描述>
  12. *
  13. * @author http://www.cnblogs.com/simoncook
  14. * @version [版本号, 2017年11月4日]
  15. * @see [相关类/方法]
  16. * @since [产品/模块版本]
  17. */
  18. @RunWith(SpringJUnit4ClassRunner.class)
  19. @ContextConfiguration(locations={"/applicationContext.xml"})
  20. public class UserServiceAssemblyByJUnit
  21. {
  22. private UserService userService;
  23. @Test
  24. public void test()
  25. {
  26. assertNotNull(userService);
  27. }
  28. public UserService getUserService()
  29. {
  30. return userService;
  31. }
  32. @Autowired
  33. public void setUserService(UserService userService)
  34. {
  35. this.userService = userService;
  36. }

分析方式

this.userService = userService; 这一行直接断点

堆栈信息

  1. org.simonme.srcstudy.spring3.demo.stub.UserServiceAssemblyByJUnit.setUserService(org.simonme.srcstudy.spring3.demo.service.UserService) line: 50
  2. sun.reflect.NativeMethodAccessorImpl.invoke0(java.lang.reflect.Method, java.lang.Object, java.lang.Object[]) line: not available [native method]
  3. sun.reflect.NativeMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 39
  4. sun.reflect.DelegatingMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 25
  5. java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 597
  6. org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues) line: 582
  7. org.springframework.beans.factory.annotation.InjectionMetadata.inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues) line: 84
  8. org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String) line: 282
  9. org.springframework.beans.factory.support.DefaultListableBeanFactory(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory).populateBean(java.lang.String, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.BeanWrapper) line: 1074
  10. org.springframework.beans.factory.support.DefaultListableBeanFactory(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory).autowireBeanProperties(java.lang.Object, int, boolean) line: 374
  11. org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(org.springframework.test.context.TestContext) line: 110
  12. org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(org.springframework.test.context.TestContext) line: 75
  13. org.springframework.test.context.TestContextManager.prepareTestInstance(java.lang.Object) line: 321
  14. org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest() line: 220
  15. org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall() line: 301
  16. org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1(org.junit.internal.runners.model.ReflectiveCallable).run() line: 12
  17. org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(org.junit.runners.model.FrameworkMethod) line: 303
  18. org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(org.junit.runners.model.FrameworkMethod, org.junit.runner.notification.RunNotifier) line: 240
  19. org.springframework.test.context.junit4.SpringJUnit4ClassRunner(org.junit.runners.BlockJUnit4ClassRunner).runChild(java.lang.Object, org.junit.runner.notification.RunNotifier) line: 50
  20. org.junit.runners.ParentRunner$3.run() line: 238
  21. org.junit.runners.ParentRunner$1.schedule(java.lang.Runnable) line: 63
  22. org.springframework.test.context.junit4.SpringJUnit4ClassRunner(org.junit.runners.ParentRunner<T>).runChildren(org.junit.runner.notification.RunNotifier) line: 236
  23. org.junit.runners.ParentRunner<T>.access$000(org.junit.runners.ParentRunner, org.junit.runner.notification.RunNotifier) line: 53
  24. org.junit.runners.ParentRunner$2.evaluate() line: 229

看junit的运作方式

从main方法到runner

翻看官方guide 很容易发现JUnitCore是main方法所在类

JUnitCore是如何到runner的呢? 看下面分析

  1. org.junit.runner.JUnitCore.main(String...)
  2. // 一些listener构造之类,然后通过AllDefaultPossibilitiesBuilder 构建runner
  3. org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(Class<?>)
  4. List<RunnerBuilder> builders = Arrays.asList(
  5. ignoredBuilder(),
  6. annotatedBuilder(),
  7. suiteMethodBuilder(),
  8. junit3Builder(),
  9. junit4Builder());
  10. for (RunnerBuilder each : builders) {
  11. Runner runner = each.safeRunnerForClass(testClass);
  12. if (runner != null) {
  13. return runner;
  14. }
  15. }

找到一个就直接返回

ignoredBuilder 可以用过Ignore注解忽略你的test case

annotatedBuilder 是找 RunWith注解定义的自定义runner

junit3Builder 如果test case 继承自TestCase类 则用junit3的runner

junit4Builder 直接对接 BlockJUnit4ClassRunner

spring的SpringJUnit4ClassRunner也是继承自BlockJUnit4ClassRunner

回头去看上面的堆栈信息 一目了然

关键点在于重写 org.junit.runners.BlockJUnit4ClassRunner.createTest() 这个方法

  1. protected Object createTest() throws Exception {
  2. return getTestClass().getOnlyConstructor().newInstance();
  3. }
  1. /**
  2. * Delegates to the parent implementation for creating the test instance and
  3. * then allows the {@link #getTestContextManager() TestContextManager} to
  4. * prepare the test instance before returning it.
  5. *
  6. * @see TestContextManager#prepareTestInstance(Object)
  7. */
  8. @Override
  9. protected Object createTest() throws Exception {
  10. Object testInstance = super.createTest();
  11. getTestContextManager().prepareTestInstance(testInstance);
  12. return testInstance;
  13. }

也就是把JUnit原生的创建test case的instance的过程接用spring容器装配的方式接管过来就可以了。

理一理Spring如何对接JUnit的更多相关文章

  1. spring框架和junit框架结合使用案例

    package ltssh; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.be ...

  2. Spring Boot 解决方案 - JUnit 测试

    简单的 JUnit 项目 回顾一下创建并运行简单的 JUnit 测试项目,先添加 JUnit 依赖然后编写类似如下模板的测试类,使用 IDE 的话直接用插件运行就行, 使用 Maven 的话运行命令 ...

  3. Spring框架下Junit测试

    Spring框架下Junit测试 一.设置 1.1 目录 设置源码目录和测试目录,这样在设置产生测试方法时,会统一放到一个目录,如果没有设置测试目录,则不会产生测试代码. 1.2 增加配置文件 Res ...

  4. Spring中的Junit

    Spring中的Junit package com.imooc.test.base; import org.junit.After; import org.junit.Before; import o ...

  5. spring入门-整合junit和web

    整合Junit 导入jar包 基本 :4+1 测试:spring-test-5.1.3.RELEASE.jar 让Junit通知spring加载配置文件 让spring容器自动进行注入 1234567 ...

  6. Spring Boot 整合Junit和redis

    14. Spring Boot整合-Junit 目标:在Spring Boot项目中使用Junit进行单元测试UserService的方法 分析: 添加启动器依赖spring-boot-starter ...

  7. [Java] Spring + SpringMVC + Maven + JUnit 搭建

    示例项目下载: https://github.com/yangyxd/SpringDemo 利用前面 SpringMVC 项目的配置方式,完成初步的项目创建.下面只讲一些不同之处. 传送门: [Jav ...

  8. spring && Cobertura && maven &&junit 单元测试以及测试覆盖率

    1. 目的:       junit 单元测试,Cobertura   测试覆盖率报告       项目目录结构          2. maven 配置     <project xmlns= ...

  9. Spring MVC实现Junit Case

    Spring MVC中编写单元测试(WEB项目): 1. 首先开发一个基类,用于载入配置文件.以下所有的测试实现类都要继承这个类 package com.yusj.basecase; import o ...

随机推荐

  1. npm相关命令

    npm install npm install log4js npm list npm list log4js #查看模板安装版本 npm install log4js@1.0.1 #指定模块版本安装 ...

  2. PHP 解决同一个IP不同端口号session冲突的问题

    在项目的开发阶段,我们经常会遇到几个站点共用同一个IP用不同端口号区分的形式!但是,这样很容易导致一个问题,session冲突丢失!即两个站点具有相同的session变量,清除session的时候即全 ...

  3. App测试流程及测试点

    1 APP测试基本流程 1.1流程图 接收版本 尽快申请到正式环境下测试 不符 App测试版本送测规范 用户行为统计测试 后台订单统计测试 尽快申请到正式环境下测试 兼容性测试.性能压力测试 功能测试 ...

  4. 似水流年 ? Chrome调试大全

    http://www.360doc.com/content/12/1107/20/7851074_246467307.shtml   作为一名前端开发者,打交道最多的可能是和浏览器.市面上各种浏览器多 ...

  5. UVA 10905 Children's Game (贪心)

    贪心,假如任意给出一个序列,如果两两交换了以后会变大,那么就交换,直到不能交换为止. #include<bits/stdc++.h> using namespace std; ; stri ...

  6. 个人作业-Alpha项目测试

    姓名 蒋东航 学号 201731062328 这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求链接 团队名称 机你太美(团队博客链接) 这个作业的目标 了解其他团队项目,学习其他团队优秀方 ...

  7. groups - 显示用户所在的组

    总览 (SYNOPSIS) groups [OPTION]... [USERNAME]... 描述 (DESCRIPTION) --help 显示此帮助, 然后退出 --version 显示版本信息, ...

  8. 实验1 c语言最基本内容

    part 1 验证性内容 总结:经受了数组和结构体的双重折磨后,发现这部分好简单...现在没啥问题了... part  2  补全程序 1.判断奇偶 // 程序功能: // 要求用户从键盘输入一个整数 ...

  9. 01_11_Strtus2简单数据验证

    01_11_Strtus2简单数据验证 1. 引入struts标签 <%@taglib uri="/struts-tags" prefix="s" %&g ...

  10. Core BlueTooth官方文档翻译

    本⽂文是苹果<Core Bluetooth Programming Guide>的翻译. 关于Core Bluetooth Core Bluetooth 框架提供了蓝⽛牙低功耗⽆无线设备与 ...