Spring -- Junit test tool, property injection method, annotation

Keywords: xml Junit Spring Attribute

1. Junit test tool

Junit is a unit testing framework for Java programming language

Common comments are:

  • @BeforeClass: indicates that the method using this annotation is executed before the test class is called. This annotation can only be declared once in a test class, and the method corresponding to this annotation can only be executed once.
  • @AfterClass: indicates that the method using this annotation is executed before the test class is called and exits. This annotation can only be declared once in a test class, and the method corresponding to this annotation can only be executed once.
  • @Before: indicates how many @ Test annotation methods in a class are executed before each @ Test call, and how many times the @ before annotation method will be called.
  • @After: indicates how many @ Test annotation methods in a class are executed after each @ Test call, and how many times the @ Before annotation method will be called.
  • @Test: indicates that the method using this annotation is a unit test case, which can be declared multiple times in a test hierarchy. Each method annotated @ test is executed only once

The complete execution sequence of Junit test cases:

  • @BeforeClass–>@Before–>@Test–>@After—>@AfterClass

Test verification:

  • The classes to be created are marked with the following red boxes:

  • Write an entity class Student first

package com.zz.domain;

public class Student {

    private int id; //Student ID
    private String name; //Full name
    private String gender; //Gender
    private String birthday; //Date of birth
    private String major; //major

    public Student() {
    }

    public Student(int id, String name, String gender, String birthday, String major) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.birthday = birthday;
        this.major = major;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", birthday='" + birthday + '\'' +
                ", major='" + major + '\'' +
                '}';
    }
}
  • Then write applicationContext.xml document
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="s1" class="com.zz.domain.Student">

    <property name="id" value="001"/>
    <property name="name" value="Zhang Yi"/>
    <property name="gender" value="male" />
    <property name="birthday" value="2009-05-18"/>
    <property name="major" value="Jiu Yin Zhen Jing" />
    </bean>

    <bean id="s2" class="com.zz.domain.Student">
        <property name="id" value="002"/>
        <property name="name" value="Huang two"/>
        <property name="gender" value="male" />
        <property name="birthday" value="2011-07-08"/>
        <property name="major" value="Buddha's palm" />
    </bean>
</beans>
  • Write test class StudentDomainTest
package com.zz.domain;

import org.junit.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentDomainTest {
    private static ApplicationContext context;

    //@BeforeClass, the initialization process of the test class, is only initialized once.
    @BeforeClass
    public static void initContext(){
        System.out.println("Implemented@BeforeClass Of initContext()...");
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    //Used to initialize test cases. Each test is executed.
    @Before
    public void initTest(){
        System.out.println("Implemented@Before Of initTeset()...");
    }

    @After
    public void afterTest(){
        System.out.println("Implemented@After Of afterTeset()...");
    }

    //test case
    @Test
    public void testGetStudents1(){
        //Initialization context (IOC container)
        //ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("Implemented@Test Of testGetStudents1()...");
        Student s1 = (Student) context.getBean("s1");
        System.out.println(s1);
    }

    //test case
    @Test
    public void testGetStudents2(){
        //Initialization context (IOC container)
        //ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("Implemented@Test Of testGetStudents2()...");
        Student s2 = (Student) context.getBean("s2");
        System.out.println(s2);
    }

    @AfterClass
    public static void destroy(){
        System.out.println("Implemented@AfterClass Of destroy()...");
    }
}
  • Operation result

2. Five uses of getBean

(1)getBean(String id/name)
id cannot be duplicate, only one can be written, and cannot be duplicate with name
name can write multiple, and it can't be the same as id

<bean id="s1" class="com.zz.domain.Student">
<bean name="name1,name2,name3" class="com.zz.domain.Student">

Type conversion required

 Student s1 = (Student) context.getBean("s1");

(2)getBean(Class clazz)
By type loading, the required type cannot be duplicate. The benefit: no type conversion required

Student s1 = context.getBean(Student.class);

(3)getBean(String id/name,Class clazz);
The advantage of id/name and type lookup is that no type conversion is required.

Student s1 = context.getBean("s1", Student.class);

(4)getBean(Class clazz,Object ...objs)

Student s1 = context.getBean(Student.class,new Object[]{003,"Hu San","female","1999-11-10","Eighteen dragon subduing palms"});

If the second parameter has an object array, you must want to return the object that uses the object array to initialize the property. The result of the run is the same as the previous object.
Solution: generate objects through factory pattern

Factory class StudentFactory

package com.zz.factory;
import com.zz.domain.Student;
import java.lang.reflect.Constructor;

//Use the factory model to generate students.
public class StudentFactory {

    public static Student getStudentInstance(int sid,String sname,String gender,String birthday,String major) throws Exception{
        Class clazz = Class.forName("com.zz.domain.Student");
        //Reflect the construction method.
        Constructor constructor = clazz.getConstructor(int.class,String.class,String.class,String.class,String.class);
        return (Student)constructor.newInstance(sid,sname,gender,birthday,major);
    }
}

applicationContext.xml document

 <!--prototype Prototype (not single case)-->
    <bean id="s1" factory-method="getStudentInstance" class="com.zz.factory.StudentFactory" scope="prototype">

        <constructor-arg name="id" value="111"/>
        <constructor-arg name="name" value=""/>
        <constructor-arg name="gender" value=""/>
        <constructor-arg name="birthday" value=""/>
        <constructor-arg name="major" value=""/>
    </bean>

Operation result

(5)getBean(String id/name,Object ...objs)
As in (4), the factory method is used to generate the object, and objs initializes the parameter list of the object

3. Attribute injection mode

In the actual project development, applicationContext.xml is generally not configured, which is too cumbersome. Annotations are used to inject
In applicationContext.xml, you only need to open the annotation:

<context:component-scan base-package="com.zz"/> 

XML configuration: simply speaking, it is to configure applicationContext.xml. To inject objects.

Annotation Configuration: if @ Configuration annotation is added to the class, the class function is equivalent to applicationContext.xml

@Bean annotations are equivalent to

(1) Through property injection

applicationContext.xml document

 <bean id="s2" class="com.zz.domain.Student">
     <property name="id" value="002"/>
     <property name="name" value="Huang two"/>
     <property name="gender" value="male" />
     <property name="birthday" value="2011-07-08"/>
     <property name="major" value="Buddha's palm" />
    </bean>
</beans>

Test class

  @Test
    public void testPropertiesInject(){
        //1. Through property injection
        Student s1 = (Student) context.getBean("s2");
        System.out.println(s1);  //Student{id=2, name = Huang Er, gender = male, birthday = 2011-07-08, major = Tathagata palm}
    }

(2) Through constructor Arg injection, the essence is to call the constructor

applicationContext.xml document

 <!--Construction method injection-->
    <bean name="hehe,haha" class="com.zz.domain.Student">
    <constructor-arg name="id" value="111"/>
    <constructor-arg name="name" value="Guo San"/>
    <constructor-arg name="gender" value="male"/>
    <constructor-arg name="birthday" value="1999-09-10"/>
    <constructor-arg name="major" value="Jiu Yin Zhen Jing"/>
    </bean>

Test class

@Test
    public void testPropertiesInject(){
        //Injection by construction method
        Student s1 = (Student) context.getBean("haha");
        System.out.println(s1);  //Student{id=111, name = Guo San, gender = male, birthday = 1999-09-10 ', major = nine Yin Scripture}
    }

(3) Inject via @ Value annotation, not recommended
Open annotation method: add in applicationContext.xml
<context:component-scan base-package="com.zz"/>

<!--@ValueAnnotation injection-->
    <!--Enable annotation function-->
    <context:component-scan base-package="com.zz"/>
    <bean name="hehe,haha" class="com.zz.domain.Student" scope="prototype">

    </bean>

Class Student
Add @ value("xxx") before the member variable, which will cause any Students object to be initialized and the property assignment is the same, so it is not recommended.

@Value("777")
private int id; //Student ID
@Value("Saturday")
private String name; //Full name
@Value("male")
private String gender; //Gender
@Value("1998-02-03")
private String birthday; //Date of birth
@Value("Fucking great")
private String major; //major

Test class

@Test
    public void testPropertiesInject(){
        //Inject via @ Value
        Student s1 = (Student) context.getBean("haha");
        System.out.println(s1); //Student{id=777, name = Saturday ', gender = male', birthday = 1998-02-03 ', major = bragging'}
    }

(4) Use @ Bean injection with @ Configuration
Create a SpringConfiguration class

package com.zz.config;

import com.zz.domain.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//A class annotated with @ Configuration is equivalent to applicationContext.xml
@Configuration
public class SpringConfiguration {

    //An object with id=haha is initialized in the IOC container
    @Bean("haha")
    public Student getStudentsBean1(){
        Student s = new Student(666,"Guo 9","male","2009-10-10","draw");
        return s;
    }

    @Bean("xixi")
    public Student getStudentsBean2(){
        Student s = new Student(200,"Chen San","female","2000-10-10","Fine Arts");
        return s;
    }
}

Similarly, in applicationContext.xml, you only need to open the annotation:
Add < context: component scan base package = "com.zz" / >

Test class

@Test
    public void testPropertiesInject(){
        //Inject by annotation
        Student s1 = (Student) context.getBean("xixi");  
        //Change to haha, and you will get Student{id=666, name = Guo Jiu, gender = male, birthday = 2009-10-10, major = painting}
        System.out.println(s1); //Student{id=200, name = Chen San, gender = female, birthday = 2000-10-10, major = art}
    }

4. bean's life range and loading strategy

Life span:

  • scope has two common attributes: singleton (singleton) and prototype (prototype). Singleton by default.

  • singleton: no matter how many times this bean is fetched, it is the same object

    <bean id="001" class="com.zz.domain.Student">
    
  • prototype: the object fetched by each bean is different

    <bean id="001" class="com.zz.domain.Student" scope="prototype">
    
  • Corresponding notes:

     @Scope("singleton")  or  @Scope("prototype")
    

Load policy:

Add on entity class

 @Component
 @Lazy(true/false)

@Lazy(true) means lazy loading. When you use it, you can call the constructor to instantiate the bean. If you don't need to, you can't instantiate it
@Lazy(false) means active loading, which is false by default; whether it is used or not, it will be loaded in advance

5. User defined attribute injection method

For example, the entity class People has complex attribute Car

Create two entity classes People and Car

package com.zz.domain;

public class Person {
    private String name;
    private String gender;
    private int age;
    private Car car;

    public Person() {
    }

    public Person(String name, String gender, int age, Car car) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.car = car;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", car=" + car +
                '}';
    }
}
package com.zz.domain;

public class Car {

    private String brand;
    private String color;
    private int price;

    public Car() {
    }

    public Car(String brand, String color, int price) {
        this.brand = brand;
        this.color = color;
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }
}

Create an annotation configuration class SpringConfiguration2

package com.zz.config;

import com.zz.domain.Car;
import com.zz.domain.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfiguration2  {
    @Bean("p1")
    public Person getPerson1(@Autowired Car car){
        //Inject a Car by type
        return new Person("Zhang San","male",30,car);
    }

    @Bean("car1")
    public Car getCar1(){
        return new Car("BMW","black",400000);
    }
}

Create PersonDomainTest test test class

package com.zz.domain;

import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PersonDomainTest {


    private static ApplicationContext context;

    //@BeforeClass, the initialization process of the test class, is only initialized once.
    @BeforeClass
    public static void initContext(){
        System.out.println("Implemented initContext..");
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
    
    @Test
    public void testGetPersonBean(){
        Person p = (Person) context.getBean("p1");
        System.out.println(p); //Person{name = 'Zhang San', gender = 'male', age=30, car=Car{brand='BMW', color =' Black ', price=400000}}}
    }
}

6. The function of various annotations in spring

@Component: added to entity class, indicating that it is a component
@Repository: added to an interface, indicating that it is an interface
@Controller: added to the control layer, indicating that it is a controller. Controller belongs to spring MVC
@Service: added to the service layer, indicating the service layer code
@Autowire: Auto inject, depending on type
@Resource: Auto inject, based on name
@Bean: represents a bean object
@Configuration: configuration notes
@Scope: life span
@Lazy: load policy

Published 47 original articles, won praise 1, visited 1663
Private letter follow

Posted by Sanoz0r on Sun, 16 Feb 2020 23:18:51 -0800