java: Junit test reflection annotation

Keywords: Java unit testing

Junit

1 what is Junit test: it is a kind of white box test (white box test is more advanced)

                          

  2 how to use Junit class:

        1. First define a test class:

                        

                                         

         code:

                                :

          2. Operation test:

                          

          Code: Note: add dependency after @ Test

                            

          3 view the judgment result (assertion): use the assertEquals method to compare the assertion result with the actual result

                        

                 Green is success

                                

                 If the result is red, it is failure

                        ​​​​​​​        

          4. Supplementary knowledge points: @ Before and @ After will be executed regardless of whether there is abnormal noise in the test

                @ Before modified methods are executed before all test methods, and are usually used to apply for resources

                 @ After modified methods are executed before all test methods, and are usually used to free resources

reflex

1 what is reflection: reflection is the encapsulation of class attributes (member variables, construction methods and member methods). Each part is encapsulated into fields, constructor and method class objects through the class loader, which is convenient for us to use these methods from memory. Reflection is the soul of frame design.

All the methods that can be called by String string are encapsulated and stored in the method class object of java. When we list these methods, the reflection mechanism is enabled.

 

  2 three ways to obtain bytecode Class objects

        ​​​​​​​        

package com.bed.java.Junit.reflect;
//There are three ways to export class files
public class ReflectDemo01 {
    public static void main(String[] args) throws Exception {
        //The first method: directly use the class static method to view the class object
        Class aClass = Class.forName("com.bed.java.Junit.reflect.Person");
        System.out.println(aClass);
        //The second way is to export class objects by class names
        Class aClass1 = Person.class;
        System.out.println(aClass1);
        //The third way is to get the class object through the object
        Person p=new Person();
        Class aClass2 = p.getClass();
        System.out.println(aClass2);

        System.out.println(aClass==aClass1);
        System.out.println(aClass==aClass2);
    }
}

          The last two lines are to prove that the address of the. Class file of the same class is unchanged no matter how it is obtained

Functions of 3class objects

         ​​​​​​​          1. Get member variables: get all member variables. getfields

                                            Gets the specified member variable. getfield("specified name")

        Class<Person> personClass = Person.class;
        //Gets all public variables of the Person object
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            /*The result of traversal is only a member variable, because a is public modified,
             No other scopes except those modified by public*/
            System.out.println(field);
        }
        //Gets the specified public variable of the Person object
        Field a = personClass.getField("a");
        Person p=new Person();

                                                                                    Note: only public modified member variables can be obtained

        In order to obtain all member variables, we can use the getdeclaraedfields method:

 //Use getdeclaraedfields(); Method to get all (public private) member variables
            Field[] declaredFields = personClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println(declaredField);
            }
        }

          2 get the value of the member variable and assign a value to the member variable: get/set

//Gets the specified public variable of the Person object
        Field a = personClass.getField("a");
        Person p=new Person();
        //Use field to obtain the value of the member variable: this step is opposite to the usual, using the member variable a,
        // Pass the object p of the class Person where a is located to get the value of the a member variable in the Person class
        Object o = a.get(p);
        System.out.println(o);//null
        //Set the value of the member variable a
        a.set(p,"bed");
        System.out.println(p);//Person{name='null', age=0, a='bed'}

        If the member variable is a private member variable, you can use: getDeclaredField("name") to get any specified value

         For member variables, if you want to read or set private variables, use the setAccessible(true) method;

        This step is often referred to as ignoring the security check of access rights (violent reflection)

//Gets the specified private variable of the Person object
Field name = personClass.getDeclaredField("name");//Gets the name private member variable in Person
name.setAccessible(true);//Ignore security checks for access rights (violent reflection)
Object o1 = name.get(p);
System.out.println(o1);

        3. Get class construction method: get null parameter construction object and parametric construction object

package com.bed.java.Junit.reflect;

import java.lang.reflect.Constructor;

public class Demo03Constructor {
    public static void main(String[] args) throws Exception {
        Person p=new Person();
        Class pClass = p.getClass();//Get class object
        //Gets the constructor (null parameter) of the class
        Object person = pClass.newInstance();
        //Get class constructor (with parameters): construction methods are distinguished according to construction parameters, so enter the type of construction parameters to find the construction method
        //The parameterized constructor of the Person object is a name of type String and an age of type int
        Constructor constructor = pClass.getConstructor(String.class, int.class);//Get constructor
        System.out.println(constructor);
        //Use the constructor to create the object, and call the newInstance method of the constructor to create the Person object
        Object person1 = constructor.newInstance("bed", 23);
        System.out.println(person1);
    }
}

                         The use method of getdeclaraedconstructor is the same as that of Field object, which will not be described here

         4. Get the member method of the class: getMethod (method three elements)

package com.bed.java.Junit.reflect;

import java.lang.reflect.Method;

public class Demo04Method {
    public static void main(String[] args) throws Exception {
        Person p=new Person();
        Class pClass = p.getClass();
        //Three parameters can be passed in: 1 method name 2 method return value 3 parameters required by member methods
        //That is, the three elements of the method
        Method eat = pClass.getMethod("eat", String.class);//Pass in the method name and method parameters here
        //Parameters are passed to the parameters of the Person object and the member method, and then the invoke execution method is called.
        eat.invoke(p, "hamburger");
    }
}

        Note: 1. If you want to view all member methods getMethods, there will be some hidden methods in the displayed results,

                    That is, the member method of the Object class

                    2. Getdeclaraedmethods uses the same as Field.

                    3. After obtaining the Method object, you can also use. getName to return and obtain the member Method name (tossing back and forth)

Exercise: use configuration file and reflection to display different methods in different classes by configuring external txt files

        1: First of all, understand what a configuration file is, which can be popularly understood as the content of a file (txt format)

              Manipulation to realize the change of operation results. Note: in this case, this file is used to control class files and is newly created

               It should be at the same level as the. class file, that is, at the same level as src.

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

          2 use configuration file: in the configuration file, we want to store two variables, class 1 name and class 2 method. Storage form we

            Use Properties (because it is in the txt file). Note: the class name should be written in the absolute path

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​

          3 code implementation

package com.bed.java.Junit.reflect;

import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

//Without moving the source code, the methods of realizing the two classes are freely switched by the operator
public class Demo05PeiZhiWenJian {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //Create a Properties collection to receive class names and class methods. Here, we take the basic Properties of the class as the key, and the real name of the class is the value
        Properties pro=new Properties();
        FileReader fr=new FileReader("D:\\study\\high level code\\day10-code test\\class.txt");//Create a new read path for the configuration file
        pro.load(fr);//The resource starts loading through the path
        fr.close();//Close flow
        //Get the current corresponding value through the classname and classmethodname keys in the txt document
        String className = pro.getProperty("className");
        String classmethodname = pro.getProperty("classmethodname");
        //Use reflection to execute methods
        //1. Create a class object and pass the class name obtained above
        Class<?> classname1 = Class.forName(className);
        //Get the member method of the class, and pass the name of the class method obtained above
        Method method = classname1.getMethod(classmethodname);
        //Gets the parameterless constructor of the class
        Constructor<?> constructor = classname1.getConstructor();
        //Create an object through the obtained construction method
        Object o = constructor.newInstance();
        //Execution method
        method.invoke(o);
    }
}

  Notes:

1. What is annotation: the description in api, @ overide @ functional interface   These are notes.

2. Function of annotation:

        ​​​​​​​        

          1. What it says is to make an index document by yourself, as shown in the figure below. First, manually write notes in the code

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​          

              Then use cmd   Run the class AnnoDemo01

        ​​​​​​​        ​​​​​​​        

              The following results appear

                                        

3. Some customized annotations in JDK:

        1 , 

        2. Functional interface: judge whether it is a functional interface  

        3,

                      For example, when you want to replace the show01 method with the new show02 method without deleting the old method

                                                 

         4,

                  Note that the red circle in the figure is some warnings automatically prompted by java. At this time, the warnings are not suppressed

         Use @ SuppressWarnings to suppress warnings, write this annotation in front of the class name, write all, and all yellow bars disappear

4 essence of Annotation: it is essentially an Annotation interface. The abstract methods in the interface are called Annotation attributes

5 how to customize annotations: the annotation format is as follows

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        The attributes of annotations can be of the following types:

                                                 

          If we define the annotation attribute on the top, we will assign values to the annotation when using the annotation. We need to pay attention to the following points

        ​​​​​​​        

          Example: simultaneous use   1 basic data type 2 enumeration 3 annotation 4 character group   Custom annotations as attributes

        ​​​​​​​        ​​​​​​​        ​​​​​​​        

6 meta annotation of annotation: that is, the annotation explaining annotation, which is usually written on the annotation interface. There are usually four elements in it

                          

          1Target: the string group passed in braces is used to limit where the annotation can be used, as shown in the following figure. Description:

                         This annotation can be used on (TYPE class, file member variable, METHOD member METHOD)

        ​​​​​​​        

          2rretention: explain the stage in which the current annotation is retained. Usually, we will define it in the RUNITIME stage.

        3Documented: enables the current annotation to appear on the api document

        4Inherited  : Subclasses inherit parent annotations

Example: replace the configuration file with annotations. The key point: how to get the attribute (method) in the annotation interface

package com.bed.java.Junit.Annotation;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/*Replace the configuration file with annotations*/
//In the annotation, we write the data of the two parameters required in the annotation
@Peizhiwenjian(classname = "com.bed.java.Junit.Annotation.eat",methodname = "chifan")
public class AnnoReflect {
    public static void main(String[] args) throws Exception {
        //The first step is to get the parameter data in the annotation to the main program (parse the annotation)
            //1.1 get the bytecode object of the current class first
            Class<AnnoReflect> annoReflectClass = AnnoReflect.class;
            //Get the annotation object of the current class with bytecode object (pass the annotation you want with the parameter)
            //Note that this anno is a subclass implementation class of an interface
            Peizhiwenjian anno = annoReflectClass.getAnnotation(Peizhiwenjian.class);
            //Use the annotation object to obtain the properties of the current annotation (that is, the abstract method of the annotation)
            //The return value at this time is the configuration value annotated at the top
            String classname = anno.classname();//com.bed.java.Junit.Annotation.eat
            String methodname = anno.methodname();//chifan
            System.out.println(classname);

            //Use reflection to execute methods
            //1. Create a class object and pass the class name obtained above
            Class<?> classname1 = Class.forName(classname);
            //Get the member method of the class, and pass the name of the class method obtained above
            Method method = classname1.getMethod(methodname);
            //Gets the parameterless constructor of the class
            Constructor<?> constructor = classname1.getConstructor();
            //Create an object through the obtained construction method
            Object o = constructor.newInstance();
            //Execution method
            method.invoke(o);
    }
}

Example 2   Custom annotation to implement: there are four member methods in the class   Find out whether the four member methods are running normally

        (note)   Also create a new error log to receive error messages. Note: the error log is captured in invoke

            When the keyword appears, the Exception automatically captured by catch can be customized. Detailed analysis of subsequent bug s

                 get.class   get.massage   get.cause   Just get.simplename (I don't know how to read videos)

Test class
package com.bed.java.Junit.Annotation.CalcTest;
//Define a calculator class with four member methods. Check whether these four methods can be executed normally
public class Calculator {
    @Check
    public void add(){
        int num=1/0;
        System.out.println("1+0="+(1+0));
    }
    @Check
    public void sub(){
        System.out.println("1-0="+(1-0));
    }
    @Check
    public void mult(){
        System.out.println("1*0="+1*0);
    }
    @Check
    public void div(){
        System.out.println("1/0="+1/0);
    }
    public void noPro(){
        System.out.println("no problem");
    }

}

Annotation interface
package com.bed.java.Junit.Annotation.CalcTest;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
}


Test procedure code:
package com.bed.java.Junit.Annotation.CalcTest;

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

public class CalcTest {
    public static void main(String[] args) throws IOException {
        //The first step is to create a txt file to record bug s
        int num=0;//This is used to record the number of bug s
        BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));
        //The second step is to find all member methods in the Calculator
        //Judge whether the method has Check annotation
        //1. Gets the Calculator bytecode file object
        Class<Calculator> calculatorClass = Calculator.class;
        //2. All methods to get bytecode files
        Method[] methods = calculatorClass.getMethods();
        //3. Traverse the obtained method group
        for (Method method : methods) {
            //See if each item has a note
            if (method.isAnnotationPresent(Check.class)){
                //If there is a Check annotation, the method will be executed. At this time, an exception will appear in invoke, which is an exception at run time
                //We use trycatch to catch exceptions and log them
                try {
                    method.invoke(new Calculator());
                } catch (Exception e) {//Catch exceptions and record them in the log. Here is a custom catchException
                    num++;//+ 1 for every bug
                    bw.write("appear bug Method name:"+method.getName());
                    bw.newLine();//Line feed
                    //Gets the short class name of the exception
                    bw.write("The exception name is:"+e.getCause().getClass().getSimpleName());
                    bw.newLine();//Line feed
                    bw.write("Cause of abnormality:"+e.getCause().getMessage());
                    bw.newLine();//Line feed
                    bw.write("=====================");
                    bw.newLine();//Line feed
                }
            }
        }
        bw.write("Total number of exceptions:"+num);
        bw.flush();
        bw.close();
    }
}

                 Log results:

 

 

Posted by Michdd on Tue, 28 Sep 2021 11:25:51 -0700