Java annotations and unit testing

annotation

Java Annotations is a new feature that appears after JDK1.5, used to illustrate the procedure, the main role of annotations in the following areas:

  1. Compilation checking, for example @Override
  2. Writing documentation, java doc will generate a corresponding document according to notes
  3. Code analysis, code analysis by Comments [using reflection]

There are some common JDK built-in annotation, such as:

  1. Override: Check the modified method whether the annotation is the parent class of rewriting
  2. Deprecatedd: The annotation content is marked obsolete
  3. SuppressWarnning: suppress warnings, arguments passed all represent suppress all warnings

Custom annotation

Although a large number of built-in JDK notes, but it also allows us to customize annotations, so that the preparation for the program has brought great convenience, as some framework on the extensive use of annotations.

java annotation is essentially an inherited java.lang.annotation.Annotationinterface interface, but if you simply use the keyword interfaceto define interfaces, still not comment, merely a common interface requires the use of keywords when defining annotation @interface, the keyword will default inherited Annotationinterface and define the interface as a comment

Annotations can be defined method that returns the value of these methods can only be a basic type, String, enumerated types, annotations, and arrays of these types, we call these methods is called property.

When using annotations to note the following things

  1. You must give the property assignment notes, if you do not use the default assignment can be set default values
  2. If the property list named only one attribute value, you can not specify the name of the property at the time of assignment
  3. Using a plurality of attribute values ​​separated by commas
  4. Using array-valued property {}, whereas when only one array property value, {}can be omitted

Yuan notes

Yuan notes are used to describe annotation annotation, metadata annotations in Java provides the following several

Target

Annotations can act described position, i.e. Java code elements which can be used the comment to the source code is as follows:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}

This annotation is only one attribute value, attribute need to pass a ElementType enumerated type of array, the following enumerated type can take several values

ElementType meaning
TYPE Interfaces, classes (including comments), using the enumeration type
FIELD Field declarations (including enumeration constants)
METHOD method
PARAMETER Parameter declaration
CONSTRUCTOR Constructor
LOCAL_VARIABLE Local variable declaration
ANNOTATION_TYPE Annotation type declaration
PACKAGE Package declaration
Retention

Indicates the length of the annotation types of notes retained, there are three main stages: source stage, class object phase, operating phase; source phase only exists only in the source code, the class object stage means are compiled into .class files, class object refers to the implementation stage is loaded into memory. the default retention policy RetentionPolicy.CLASS.

Its source code is as follows:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}
Documented

It represents that it has the annotation elements can be documented by javadoc such tools. Source as follows:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
Inherited

It indicates that the annotation type is automatically inherited

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

Built-in notes reading

The following interpretation of the built-annotated to illustrate a few notes related to the use of JDK

Override
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

When checking for compiling the annotation, the annotation whether the annotation is a method of rewriting the parent class.

From the source point of view, it can only be used in the method, and it only exists in the source stage will not be compiled into .class file

Deprecatedd
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

Used to inform the compiler, a program element (for example, classes, methods, properties, etc.) is not recommended

From the source point of view, almost all of the Java program elements can use it, and will be loaded into memory

SuppressWarnning
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

Tells the compiler to ignore certain types of warnings
that need to pass an array of strings, values are as follows:
| Parameter | Meaning |
--- |: |: | ---
when using an outdated class or method | | deprecation wARNING |
| an unchecked | performs warning when unchecked conversion |
| fallthrough | when the Switch block enters into the next case without Break warning |
| path | at class path, the source file path, and so there is no path exists wARNING |
| serial | warning when the sequence of the class may be defined serialVersionUID missing |
| finally | any warning finally clause can not be normally completed |
| All | all the above cases warning |

In the program parses comment

Generally parsing custom annotations by reflection techniques, to be identified annotations by reflection technique is a prerequisite annotation is to be loaded to make it in memory for the range RUNTIME;

JDK provides the following common API to facilitate our use
| return value of | method | interpretation |
|: ----- |: --- |: ---- |
| T | getAnnotation (Class annotationClass) | When there is that element specify the type of annotation, the corresponding annotation return it, otherwise return null |
| annotation [] | getAnnotations () | returns all annotations present on this element |
| annotation [] | getDeclaredAnnotations () | returns all annotations directly present on this element . |
| Boolean | isAnnotationPresent (Class annotationClass <the extends Annotation?>) | When specifying the type of annotation presence of the element, it returns true, otherwise returns false |

Real

Use the following example to illustrate a complete custom annotation and examples of the use of annotations in the program, is now defined to mimic a MyTest JUnit annotations, notes that as long as the modified method of the future will be automatically executed

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

import java.lang.annotation.ElementType;

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

First define a comment, the follow-up to the implementation of the modified annotated with this all the way through Target to modify the notes indicate the method can only be used by modifying Retention marked notes will be retained to run

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    @MyTest
    public void test1(){
        System.out.println("this is test1");
    }

    @MyTest
    public void test2(){
        System.out.println("this is test2");
    }

    public static void main(String[] args) {
        Method[] methods = Test.class.getMethods();
        for (Method method:methods){
            if (method.isAnnotationPresent(MyTest.class)){
                try {
                    method.invoke(new Test());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

We define two test functions are used in the test class @MyTestmodification, in the main process, all of the class obtained by reflection method first, then call a method of isAnnotationPresentthe function determines whether the method is @Testmodified, and if so, perform the method. Even after this add method, as long as the @MyTestmodifications will be called.

Junit Framework

In software development in order to ensure the quality of the software unit testing is an essential part, Java provides Junit testing framework for unit testing

Usually a Java program corresponding to each class will be a test class for all codes used for the unit test, for example, a Person class, in order to test the Person class defines a class to test PersonTest

JUnit is defined in a number of notes to help us write unit tests

  1. @Test: test method, modified the annotation method is a test method
  2. @Before: This annotation performs modification methods before testing method is executed
  3. @After: This annotation will execute modified method after the test method is executed

In addition to JUnit annotation defines a number of functions to automate test assertions, several commonly used are as follows:

  1. void assertEquals (boolean expected, boolean actual): two variables or to check whether the balance equations
  2. void assertTrue (boolean expected, boolean actual): Check the condition is true
  3. void assertFalse (boolean condition): Check the condition is false
  4. void assertNotNull (Object object): object under examination is not empty
  5. void assertNull (Object object): the inspection object is null
  6. void assertSame (boolean condition): assertSame () method checks two related objects point to the same object
  7. void assertNotSame (boolean condition): assertNotSame () method checks whether or not two related objects pointing to the same object
  8. void assertArrayEquals (expectedArray, resultArray): assertArrayEquals () method checks whether the two arrays are equal

These functions after the assertion fails will throw an exception, as long as the follow-up to see anomalies which can not pass the test

Suppose define a class calculator to perform arithmetic two numbers

public class Calc {
    public int add(int a, int b){
        return a + b;
    }

    public int sub(int a, int b){
        return a - b;
    }

    public int mul(int a, int b){
        return a * b;
    }

    public float div(int a, int b){
        return a / b;
    }
}

To test these methods are correct, we define a test class

import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class CalcTest {
    @Test
    public void addTest(){
        int result = new Calc().add(1,2);
        assertEquals(result, 3);
    }

    @Test
    public void subTest(){
        int result = new Calc().sub(1,2);
        assertEquals(result, -1);
    }

    @Test
    public void mulTest(){
        int result = new Calc().mul(1,2);
        assertEquals(result, 2);
    }

    @Test
    public void divTest(){
        float result = new Calc().div(1,2);
        assertEquals(result, 0.5, 0.001); //会报异常
    }
}

After testing found last divTest method will be reported abnormal, the actual value is 0, because we use /only the reserved bit integers to calculate two int, which is obtained is 0, does not match the expected 0.5, and therefore will be reported abnormal


Guess you like

Origin www.cnblogs.com/lanuage/p/11441974.html