Junit, reflection, annotations

Junit, reflection, annotations

Junit unit test

Test categories:

  1. Black-box testing: No need to write code, give the input value to see if the program can output the expected value

  1. White box testing: need to write code, pay attention to the specific execution process of the program

Junit usage: white box testing

step

  1. Define a test class (test case)

  • suggestion:

  • Test class name: the tested class name Test

  • Package name: xxx.xxx.xxt.est

  1. Define the test method: can be run independently

  • suggestion:

  • Method name: the method name of the test test

  • return value: void

  • Parameter list: empty parameter

  1. Add @Test to the method

  1. Import junit dependent environment

critical result

  1. red: failed

  1. green: success

  1. Generally we will use the assertion operation to process the result

  • Assert.assertEquals( expected result, operation result)

Replenish

  • @Before:

  • The decorated method will be automatically executed before the test method

  • @After:

  • The modified method will be automatically executed after the test method

package com.jx.day01_basic.test;

import com.jx.day01_basic.junit.Calculator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class CalculatorTest {

    /**
     * initialization method
     * For resource application, all test methods will be executed before execution
     */
    @Before
    public void init(){
        System.out.println("init......");
    }

    /**
     * release resource method
     * Execute the method automatically after all test methods have executed
     */
    @After
    public void close(){
        System.out.println("close....");
    }

    @Test
    public void testAdd(){
        //1. Create a calculator object
        Calculator c=new Calculator();
        //2. Call the add method
        int result=c.add(1,2);
        System.out.println("testAdd...");
//        System.out.println(result);
        //3. Assertion I assert that this result is 3
        Assert.assertEquals(3,result);
    }
    @Test
    public void testSub(){
        Calculator c=new Calculator();
        int result=c.sub(1,2);
        System.out.println("testSub...");
        Assert.assertEquals(-1,result);
    }
}

reflection

The soul of frame design

  1. Framework: semi-finished software. Software development can be carried out on the basis of the framework, simplifying coding

  1. Reflection: Encapsulate the various components of the class into other objects, which is the reflection mechanism

  • benefit:

  • These objects can be manipulated while the program is running

  • Can be decoupled to improve the scalability of the program

  1. The way to get the class object

  • Class.forName("full class name"): Load the bytecode file into memory and return the Class object

  • It is mostly used in configuration files, the class name is defined in the configuration file, the file is read, and the class is loaded

  • Class name.class: obtained through the attribute class of the class name

  • It is mostly used for passing parameters

  • Object.getClass(): The getClass() method is defined in the Object class

  • It is mostly used to obtain the bytecode of the object

Summarize

The same bytecode file (*.class) will only be loaded once during a program run, no matter which method is used to obtain the Class object is the same

Class object function

  1. Get member variables

  • Filed[] getFileds() Get all public modified member variables

  • Filed[] getFileds(String name) Get the member variable of the specified public modification

  • Filed[] declareFields() Get all field variables regardless of modifiers

  1. Get constructors

  1. get member methods

  1. get class name

Filed: member variable

  • operate

  1. Settings

  • void set(Object obj´╝îObject value)

  1. get value

  • get(Object obj)

  1. Security checks that ignore access modifiers

  • setAccessible(true) violent reflection

public class ReflectDemo02 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        //0. Get the Class object of Person
        Class personClass= Person.class;
        //1.Field[] fileds Get all public modified member variables
        Field[] fileds=personClass.getFields();
        for (Field filed : fileds) {
            System.out.println(filed);
        }
        System.out.println("=========");
        //2.Filed getField(String name) Get the member variable of the specified public modification
        Field a=personClass.getField("a");
        //Get the value of member variable a
        Person p=new Person();
        Object value=a.get(p);
        System.out.println(value);
        //set the value of a
        a.set(p,"Zhang San");
        System.out.println(p);
        System.out.println("=====");

        //Field[] declareFields get all field variables regardless of modifiers
        Field[] declareFields=personClass.getDeclaredFields();
        for (Field declareField : declareFields) {
            System.out.println(declareField);
        }
        //Field   getDeclaredField(String name)
        Field d=personClass.getDeclaredField("d");
        //Security checks that ignore access modifiers
        d.setAccessible(true);//violent reflex
        Object vaule2=d.get(p);
        System.out.println(vaule2);
    }
}

Constructor: construction method

  • create object

  1. T newInstance(Object...initargs)

  1. If you use the empty parameter constructor to create the object, the operation can be simplified: the newInstance method of the class object

public class ReflectDemo03 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //0. Get the Class object of Person
        Class personClass= Person.class;

        //Constructor<T> getConstructor(class<?>...parameterTypes)
        Constructor constructor=personClass.getConstructor(String.class,int.class);
        System.out.println(constructor);
        //create object
        Object person=constructor.newInstance("Zhang San",23);
        System.out.println(person);

        Constructor constructor1=personClass.getConstructor();
        System.out.println(constructor1);
        //create object
        Object person1=constructor1.newInstance();
        System.out.println(person1);

        Object o=personClass.newInstance();
        System.out.println(o);

        constructor1.setAccessible(true);

    }
}

Method: method object

  • Execution method:

  • Object invoke(Object obj,object...args)

  • Get method name:

  • String getName: get method name

public class ReflectDemo04 {
    public static void main(String[] args) throws Exception {
        //0. Get the Class object of Person
        Class personClass= Person.class;

        //method to get the specified name
        Method eat_method=personClass.getMethod("eat",String.class);
        Person p=new Person();
        //execution method
        eat_method.invoke(p,"vegetables");

        System.out.println("........");

        //Get all public modified methods
        Method[] methods=personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
            String name=method.getName();
            System.out.println(name);
        }

        //get class name
        String className=personClass.getName();
        System.out.println(className);

    }
}

case:

  • Requirements: Write a "framework" that can help us create objects of any class and execute any method in them

  • accomplish:

  1. configuration file

  1. reflection

  • step:

  1. Define the full class name of the object to be created and the method to be executed in the configuration file

  1. Load and read configuration files in the program

  1. Use reflection techniques to load class files into memory

  1. create object

  1. execution method

className=com.jx.day01_basic.domain.Person
methodName=eat
package com.jx.day01_basic.reflect;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //Objects of any class can be created and any method can be executed

//        Person p=new Person();
//        p.eat("qq");

//        Student student=new Student();
//        student.sleep();

        //1. Load the configuration file
        //1.1 Create Properties object
        Properties pro=new Properties();
        //1.2 Load the configuration file and convert it to a collection
        //1.2.1 Obtain the configuration file in the class directory
        ClassLoader classLoader=ReflectTest.class.getClassLoader();
        InputStream is=classLoader.getResourceAsStream("pro.properties");
        pro.load(is);
        //2. Get the data defined in the configuration file
        String className=pro.getProperty("className");
        String methodName=pro.getProperty("methodName");

        //3. Load the class into memory
        Class cls=Class.forName(className);
        //4. Create method object
        Object obj=cls.newInstance();
        //5. Get the method object
        Method method=cls.getMethod(methodName);
        //execution method
        method.invoke(obj);
    }
}

annotation

Function classification:

  1. Writing documents: Generate documents through the annotations identified in the code [Generate doc documents]

  1. Code analysis: analyze the code through the annotations identified in the code [using reflection]

  1. Compilation check: Through the annotations marked in the code, the compiler can implement basic compilation checks [override]

Some annotations predefined in JDK

custom annotation

Using (parsing) annotations in the program

  • @Override: Check whether the method marked by this annotation is inherited from the parent class (interface)

  • @Deprecated: The content of the annotation indicates that it is outdated

  • @SuppressWarnings: suppress warnings

  • Generally pass parameters all @SuppressWarnings("all")

custom annotation

Format:

meta annotation

public @interface Annotation name {
}

Nature

The essence of annotation is an interface, which inherits the Annotion interface by default

public interface MyAnno extends java.lang.annotation.Annotation {

}

Attributes

Member methods that can be defined in an interface

Require:

  1. The return value type of the property

  • basic data type

  • String

  • enumerate

  • annotation

  • Arrays of the above types

  1. The attribute is defined, and it is necessary to assign a value to the attribute when using it

  • If you use the default keyword to give the attribute a default initial value when defining the attribute, you can not assign the attribute when using the annotation

  • If only one attribute needs to be assigned, and the name of the attribute is value, the value can be omitted, and the value can be defined directly

  • When assigning a value to an array, use {} to wrap it, if there is only one value in the array, then {} is omitted

meta annotation

Annotations used to describe annotations

  • @Target: Describes where the annotation can work

ElementType values:

  • TYPE: acts on the class

  • METHOD: acts on the method

  • FIELD: acting on member variables

  • @Retention: Describes the stage in which annotations are retained

  • @Retention(RetentionPolicy.RUNTIME): The currently described annotation will be retained in the class bytecode file and read by the JVM

  • @Documented: Whether the description annotation is extracted into the api document

  • @Interited: Describes whether the annotation is inherited by subclasses

@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnno3 {

}

Use annotations in the program

  • Get the attribute value defined in the annotation

  1. Get the location object defined by the annotation (Class, Method, Filed)

  1. Get the specified annotation

  public class ProImpl implements Pro{
         public String className(){
               return "com.jx.day01_basic.annotation.Demo01";
         }
         public String methodName(){
              return "show";
         }
     }
  1. Call the abstract method in the annotation to get the configured attribute value

package com.jx.day01_basic.annotation;

import java.lang.reflect.Method;

@Pro(className = "com.jx.day01_basic.annotation.Demo01",methodName = "show")
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //1. Analyzing annotations
        //1.1 Get the bytecode file object of this class
        Class<ReflectTest> reflectTestClass=ReflectTest.class;
        //2. Get the annotation object above
        //In fact, a subclass implementation object of the annotation interface is generated in memory
        Pro an=reflectTestClass.getAnnotation(Pro.class);
        //3. Call the abstract method defined in the annotation object to get the return value
        String className=an.className();
        String methodName=an.methodName();
        System.out.println(className);
        System.out.println(methodName);

        //load class
        Class cls=Class.forName(className);
        //create object
        Object obj=cls.newInstance();
        //get method object
        Method method=cls.getMethod(methodName);
        //execution method
        method.invoke(obj);
    }
}

case

package com.jx.day01_basic.annotation.demo;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.management.BufferPoolMXBean;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestCheck {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, IOException {
        //1. Create a calculator object
        Calculator c=new Calculator();
        //2. Get the bytecode file object
        Class cls=c.getClass();
        //3. Get all methods
        Method[] methods=cls.getMethods();

        int num=0;
        BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));

        for (Method method : methods) {
            //4. Determine whether there is a Check annotation on the method
            if(method.isAnnotationPresent(Check.class)){
                //5. Execution
                try{
                    method.invoke(c);
                }catch (Exception e){
                    e.printStackTrace();
                    num++;
                    bw.write(method+"method error");
                    bw.newLine();
                    bw.write("exception name"+e.getCause().getClass().getSimpleName());
                    bw.newLine();
                    bw.write("Abnormal"+e.getCause().getMessage());
                    bw.newLine();
                    bw.write(".......");
                }
            }
        }
        bw.write("In this test a total of"+num+"exception");
        bw.flush();
        bw.close();
    }
}
className=com.jx.day01_basic.domain.Person
methodName=eat

Tags: Java unit testing JavaEE Junit

Posted by aQ on Sat, 25 Mar 2023 16:52:01 +1030