摘要:本文将带你理一理测试工具中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 //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.DependencyInjectionTestExecution
Listener.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.RunNoti
fier) 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容器装配的方式接管过来就可以了。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标软件测试之测试工具频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号