理一理Spring如何对接JUnit
测试代码
package org.simonme.srcstudy.spring3.demo.stub;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.simonme.srcstudy.spring3.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* <一句话功能简述>
* <功能详细描述>
*
* @author http://www.cnblogs.com/simoncook
* @version [版本号, 2017年11月4日]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
public class UserServiceAssemblyByJUnit
{
private UserService userService;
@Test
public void test()
{
assertNotNull(userService);
}
public UserService getUserService()
{
return userService;
}
@Autowired
public void setUserService(UserService userService)
{
this.userService = userService;
}
分析方式
this.userService = userService; 这一行直接断点
堆栈信息
org.simonme.srcstudy.spring3.demo.stub.UserServiceAssemblyByJUnit.setUserService(org.simonme.srcstudy.spring3.demo.service.UserService) line: 50
sun.reflect.NativeMethodAccessorImpl.invoke0(java.lang.reflect.Method, java.lang.Object, java.lang.Object[]) line: not available [native method]
sun.reflect.NativeMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 39
sun.reflect.DelegatingMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 25
java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 597
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues) line: 582
org.springframework.beans.factory.annotation.InjectionMetadata.inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues) line: 84
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(org.springframework.beans.PropertyValues, java.beans.PropertyDescriptor[], java.lang.Object, java.lang.String) line: 282
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
org.springframework.beans.factory.support.DefaultListableBeanFactory(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory).autowireBeanProperties(java.lang.Object, int, boolean) line: 374
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(org.springframework.test.context.TestContext) line: 110
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(org.springframework.test.context.TestContext) line: 75
org.springframework.test.context.TestContextManager.prepareTestInstance(java.lang.Object) line: 321
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest() line: 220
org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall() line: 301
org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1(org.junit.internal.runners.model.ReflectiveCallable).run() line: 12
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(org.junit.runners.model.FrameworkMethod) line: 303
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(org.junit.runners.model.FrameworkMethod, org.junit.runner.notification.RunNotifier) line: 240
org.springframework.test.context.junit4.SpringJUnit4ClassRunner(org.junit.runners.BlockJUnit4ClassRunner).runChild(java.lang.Object, org.junit.runner.notification.RunNotifier) line: 50
org.junit.runners.ParentRunner$3.run() line: 238
org.junit.runners.ParentRunner$1.schedule(java.lang.Runnable) line: 63
org.springframework.test.context.junit4.SpringJUnit4ClassRunner(org.junit.runners.ParentRunner<T>).runChildren(org.junit.runner.notification.RunNotifier) line: 236
org.junit.runners.ParentRunner<T>.access$000(org.junit.runners.ParentRunner, org.junit.runner.notification.RunNotifier) line: 53
org.junit.runners.ParentRunner$2.evaluate() line: 229
看junit的运作方式
从main方法到runner
翻看官方guide 很容易发现JUnitCore是main方法所在类
JUnitCore是如何到runner的呢? 看下面分析
org.junit.runner.JUnitCore.main(String...)
// 一些listener构造之类,然后通过AllDefaultPossibilitiesBuilder 构建runner
org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(Class<?>)
List<RunnerBuilder> builders = Arrays.asList(
ignoredBuilder(),
annotatedBuilder(),
suiteMethodBuilder(),
junit3Builder(),
junit4Builder());
for (RunnerBuilder each : builders) {
Runner runner = each.safeRunnerForClass(testClass);
if (runner != null) {
return runner;
}
}
找到一个就直接返回
ignoredBuilder 可以用过Ignore注解忽略你的test case
annotatedBuilder 是找 RunWith注解定义的自定义runner
junit3Builder 如果test case 继承自TestCase类 则用junit3的runner
junit4Builder 直接对接 BlockJUnit4ClassRunner
spring的SpringJUnit4ClassRunner也是继承自BlockJUnit4ClassRunner
回头去看上面的堆栈信息 一目了然
关键点在于重写 org.junit.runners.BlockJUnit4ClassRunner.createTest() 这个方法
protected Object createTest() throws Exception {
return getTestClass().getOnlyConstructor().newInstance();
}
/**
* Delegates to the parent implementation for creating the test instance and
* then allows the {@link #getTestContextManager() TestContextManager} to
* prepare the test instance before returning it.
*
* @see TestContextManager#prepareTestInstance(Object)
*/
@Override
protected Object createTest() throws Exception {
Object testInstance = super.createTest();
getTestContextManager().prepareTestInstance(testInstance);
return testInstance;
}
也就是把JUnit原生的创建test case的instance的过程接用spring容器装配的方式接管过来就可以了。
理一理Spring如何对接JUnit的更多相关文章
- spring框架和junit框架结合使用案例
package ltssh; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.be ...
- Spring Boot 解决方案 - JUnit 测试
简单的 JUnit 项目 回顾一下创建并运行简单的 JUnit 测试项目,先添加 JUnit 依赖然后编写类似如下模板的测试类,使用 IDE 的话直接用插件运行就行, 使用 Maven 的话运行命令 ...
- Spring框架下Junit测试
Spring框架下Junit测试 一.设置 1.1 目录 设置源码目录和测试目录,这样在设置产生测试方法时,会统一放到一个目录,如果没有设置测试目录,则不会产生测试代码. 1.2 增加配置文件 Res ...
- Spring中的Junit
Spring中的Junit package com.imooc.test.base; import org.junit.After; import org.junit.Before; import o ...
- spring入门-整合junit和web
整合Junit 导入jar包 基本 :4+1 测试:spring-test-5.1.3.RELEASE.jar 让Junit通知spring加载配置文件 让spring容器自动进行注入 1234567 ...
- Spring Boot 整合Junit和redis
14. Spring Boot整合-Junit 目标:在Spring Boot项目中使用Junit进行单元测试UserService的方法 分析: 添加启动器依赖spring-boot-starter ...
- [Java] Spring + SpringMVC + Maven + JUnit 搭建
示例项目下载: https://github.com/yangyxd/SpringDemo 利用前面 SpringMVC 项目的配置方式,完成初步的项目创建.下面只讲一些不同之处. 传送门: [Jav ...
- spring && Cobertura && maven &&junit 单元测试以及测试覆盖率
1. 目的: junit 单元测试,Cobertura 测试覆盖率报告 项目目录结构 2. maven 配置 <project xmlns= ...
- Spring MVC实现Junit Case
Spring MVC中编写单元测试(WEB项目): 1. 首先开发一个基类,用于载入配置文件.以下所有的测试实现类都要继承这个类 package com.yusj.basecase; import o ...
随机推荐
- 关于死循环while(true){}或for(;;){}的总结
关于死循环while(true){}或for(;;){}的总结 1.基本用法: while(true){ 语句体; } for(;;){ 语句体; } 以上情况,语句体会一直执行. 2 ...
- Linux上通过MySQL命令访问MySQL数据库时常见问题汇总
Linux上通过mysql命令访问MySQL数据库时常见问题汇总 1)创建登录账号 #创建用户并授权 #允许本地访问 create user 'test'@'localhost' identified ...
- python+selenium之多表单切换
在Web应用中经常会遇到fram/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于fram/iframe表单内嵌套页面上的元素无法直接定位.这是需要通过swit ...
- Cesium左右立体视觉续篇——遗留问题(渲染错误)以及临时替代方案
遗留问题详细说明 已解决部分 立体视觉中的视差: 横向渲染压缩. 遗留问题 1.左右分屏中的部分地图切片未渲染 问题描述:如下图(图片为解决问题后的图片),红色区域会显示黑色,无法正常显示影像.2.相 ...
- UVA11212 EditingaBook ( IDA*搜索)
首先说说IDS,就DFS限定一个层数上限maxd,如果在maxd范围内没有找到解,就增加maxd,继续搜索. 当访问到当前结点u时,估计还要搜索h(u)层,如果h(u)+当前层数d>maxd的时 ...
- [论文理解]Selective Search for Object Recognition
Selective Search for Object Recognition 简介 Selective Search是现在目标检测里面非常常用的方法,rcnn.frcnn等就是通过selective ...
- HTML之基本语法(表单)
一.表单的基本介绍 表单:就是互联网上用于收集用户信息的一种结构,在HTML当中事先定义好了一种标签来完成此事,标签名称为form,它是一个双标签<form action="" ...
- java基础—基础语法2
一.语句
- cocos2dx for lua 摄像机移动
在cocos2dx中,我们想通过移动摄像机来做一些特殊处理,比如将摄像机聚焦在某个物体上,或者摄像机颤抖,摄像机原理观察sprite回收状况等等, 都需要通过相机移动来使用. cocos2dx中的摄像 ...
- 【线性基合并 树链剖分】bzoj4568: [Scoi2016]幸运数字
板子题 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市 ...