发表于: 2020-10-10 23:07:17

1 1397


今天完成的事情:

遇到的问题:

Spring整合JUnit(参考网址:https://zhuanlan.zhihu.com/p/41664893)

一、JUnit 常用注解的简单使用

1、常用注解

  • @Test::测试方法
  • @Ignore:被忽略的测试方法:加上之后,暂时不运行此段代码
  • @Before:每一个测试方法之前运行
  • @After:每一个测试方法之后运行
  • @BeforeClass:方法必须必须要是静态方法(static 声明),所有测试开始之前运行,注意区分 @Before
  • @AfterClass:方法必须要是静态方法(static 声明),所有测试结束之后运行,注意区分 @After

2、JUnit 的简答使用

(1)添加 JUint 依赖

<!-- 单元测试Junit -->
<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
</dependency>


(2)测试代码

public class JunitTest1 {

private UserService userService;

   @Before
   public void init() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
       userService = (UserService) context.getBean("userService");
   }

@Test
   public void test() {
userService.saveUser();
   }

}

这里我们使用了 @Before 注解来获取 Spring 容器,并获取到需要使用的 bean 实例。这样就可以做到把业务代码和获取 Spring 容器的代码分离开来,无论有多少个业务方法需要测试,都只需要添加一个 @Test 标注的方法就可,无需重复获取 Spring 容器。但是这种只是简单的使用了 JUnit,而没有与 Spring 进行整合,如果我们想要做到不写 Spring 容器初始化的代码,只用 JUnit 是做不到的,下面我们来看看如何解决这个问题。

这里不知道bean是什么?去查了一下

spring bean是什么?(参考网址:https://www.awaimai.com/2596.html#comments)

Spring有跟多概念,其中最基本的一个就是bean,那到底spring bean是什么?

Bean是Spring框架中最核心的两个概念之一(另一个是面向切面编程AOP)。

是否正确理解 Bean 对于掌握和高效使用 Spring 框架至关重要。

遗憾的是,网上不计其数的文章,却没有简单而清晰的解释。

那么,Spring bean 到底是什么?

接下来我们用图文方式来解析这一个概念。

1 定义

Spring 官方文档对 bean 的解释是:

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.

翻译过来就是:

在 Spring 中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象。

概念简单明了,我们提取处关键的信息:

1.构成程序的主干

2.由Spring IoC容器实例化、组装和管理的对象。

作者提取的

  1. 1.bean是对象,一个或者多个不限定
  2. 2.bean由Spring中一个叫IoC的东西管理
  3. 3.我们的应用程序由一个个bean构成

第1和3好理解,那么IoC又是什么东西?

昨天了解了一下IoC,所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。

举个例子,比如你中午不想动想点外卖,这时候没有美团你会怎么做呢?你还得自己出去,找一家店,吃完要到名片,下次就可以通过打电话下单了,但是你还想吃其他的,但并不知道那家好吃,总要吃过才知道。。。这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。

这时候出现了外卖软件,所有商家会在上面登记注册,无论你吃中餐还是西餐都可以在上面找到。你想好要求,然后在上面下单,就会给你送过来。简单明了,如果商家选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有外卖平台这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

2 控制反转(IoC)

控制反转英文全称:Inversion of Control,简称就是IoC

控制反转通过依赖注入(DI)方式实现对象之间的松耦合关系

程序运行时,依赖对象由【辅助程序】动态生成并注入到被依赖对象中,动态绑定两者的使用关系。

Spring IoC容器就是这样的辅助程序,它负责对象的生成和依赖的注入,让后在交由我们使用。

简而言之,就是:IoC就是一个对象定义其依赖关系而不创建它们的过程

这里我们可以细分为两个点。

2.1 私有属性保存依赖

第1点:使用私有属性保存依赖对象,并且只能通过构造函数参数传入,

构造函数的参数可以是工厂方法保存类对象的属性、或者是工厂方法返回值

假设我们有一个Computer类:

package top.alanshelby.ComputerTest;

public class Computer {
private String cpu;     // CPU型号
   private int ram;        // RAM大小,单位GB

   public Computer(String cpu, int ram) {
this.cpu = cpu;
       this.ram = ram;
   }
}

我们有另一个Person类依赖于Computer类,符合IoC的做法是这样:

package top.alanshelby.ComputerTest;


   public class Person {
private Computer computer;

       public Person(Computer computer) {
this.computer = computer;
       }
}

不符合IoC的做法如下

// 直接在Person里实例化Computer
public class Person {
private Computer computer = new Computer("AMD", 3);
}

// 通过【非构造函数】传入依赖
public class Person {
private Computer computer;

   public void init(Computer computer) {
this.computer = computer;
   }

2.2 让Spring控制类构建过程

第2点:不用new,让Spring控制new过程。

在Spring中,我们基本不需要 new 一个类,这些都是让 Spring 去做的。

Spring 启动时会把所需的类实例化成对象,如果需要依赖,则先实例化依赖,然后实例化当前类。

因为依赖必须通过构建函数传入,所以实例化时,当前类就会接收并保存所有依赖的对象。

这一步也就是所谓的依赖注入

2.3 这就是IoC

在 Spring 中,类的实例化、依赖的实例化、依赖的传入都交由 Spring Bean 容器控制,

而不是用new方式实例化对象、通过非构造函数方法传入依赖等常规方式。

实质的控制权已经交由程序管理,而不是程序员管理,所以叫做控制反转。

3 Bean?

至于bean,则是几个概念。

  • 概念1:Bean容器,或称spring ioc容器,主要用来管理对象和依赖,以及依赖的注入。
  • 概念2:bean是一个Java对象,根据bean规范编写出来的类,并由bean容器生成的对象就是一个bean。
  • 概念3:bean规范。

bean规范如下:

  1. 所有属性为private
  2. 提供默认构造方法
  3. 提供getter和setter
  4. 实现serializable接口
  5. 二.Spring 整合 Junit

1、解决思路

针对上述问题,我们需要的是程序能自动帮我们创建容器。一旦程序能自动为我们创建 Spring 容器,我们就无须手动创建了,问题也就解决了。

但紧接的问题就是 JUnit 它本身不认识 Spring,更无法帮助创建 Spring 容器了,不过好在JUnit 给我们暴露了一个注解(@RunWith),可以让我们替换掉它的运行器。

这时,我们需要依靠 Spring 框架,因为它提供了一个运行器,可以读取配置文件(或注解)来创建容器。我们只需要告诉它配置文件在哪就行了。

@RunWith

关于@RunWith注解,官方文档是这么描述的:

当使用@RunWith注释类或扩展使用@RunWith注释的类时,JUnit将调用其引用的类以在该类中运行测试,而不是JUnit内置的运行程序。

2、配置步骤

(1)添加 spring-test 依赖

<!-- 添加 spring-test 依赖 -->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>4.3.13.RELEASE</version>
</dependency>

(2)通过 @RunWith 注解,指定 Spring 的运行器,这里 Spring的运行器是SpringJunit4ClassRunner

//通过 @RunWith 注解,指定 Spring 的运行器,这里 Spring的运行器是SpringJunit4ClassRunner
@RunWith(SpringJUnit4ClassRunner.class)

(3)通过 @ContextConfiguration 注解,指定 Spring 运行器需要的配置文件路径或者配置类,这里由于我们使用的全注解的方式,所以指定的是配置类。

@ContextConfiguration(classes = SpringConfiguration.class)
//@ContextConfiguration(locations = "classpath:applicationContext.xml")


(4)通过 @Resource 或者 @Autowired 注解给测试类中的变量注入数据,推荐使用@Resource
@Resource
private UserService userService;

3、测试类代码

package test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import top.alanshelby.config.SpringConfiguration;
import top.alanshelby.service.UserService;

import javax.annotation.Resource;


//通过 @RunWith 注解,指定 Spring 的运行器,这里 Spring的运行器是SpringJunit4ClassRunner
@RunWith(SpringJUnit4ClassRunner.class)

//通过 @ContextConfiguration 注解,指定 Spring 运行器需要的配置文件路径或者配置类,这里由于我们使用的全注解的方式,所以指定的是配置类。
@ContextConfiguration(classes = SpringConfiguration.class)
//@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JunitTest2 {

@Resource
   private UserService userService;

   @Test
   public void test() {

userService.saveUser();
   }
}




明天计划的事情:
查看日志,并转成Debug模式,练习调试,学会查看单步执行时的变量值。



收获:对junit更了解了,对spring认识加深了






返回列表 返回列表
评论

    分享到