Junit测试和反射

Posted acknowledge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Junit测试和反射相关的知识,希望对你有一定的参考价值。

Junit单元测试

测试分类

  1. 黑盒测试:不需要写代码,给输入值,看程序能否得到输出期望值.
  2. 白盒测试:需要些代码,关注程序具体的执行流程.

Junit的使用

  • 步骤
    1. 定义一个测试类(测试用例).
    2. 定义测试方法,可以独立运行.
    3. 给方法加@Test.
    4. 导入junit依赖环境.
  • 判断结果
    • 红色:失败
    • 绿色:成功
    • 一般使用断言操作来处理结果.
      • Assert.assertEquals(期望的结果,运行的结果);
  • 补充
    • @Before:修饰的方法会在测试方法之前自动执行.
    • @After:修饰的方法会在测试之后自动执行.
package Junit_Demo;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class demo1 {
    @Before
    public void init()
    {
        System.out.println("init...");
    }

    @Test
    public void test1()
    {
        int a=2;
        int b=3;
        int c=a+b;
        System.out.println(c);
    }

    @Test
    public void test2()
    {
        int a=2;
        int b=3;
        int c=a+b;

        //断言:如果两个不相等,则失败.
        Assert.assertEquals(3,c);
        System.out.println(c);
    }

    @After
    public void close()
    {
        System.out.println("after...");
    }
}

反射:框架设计的灵魂

定义

  • 框架:半成品软件,可以在框架的基础上进行软件开发,简化代码量.
  • 反射:将类的各个组成部分封装为其他对象,这就是反射机制.
    • 好处
      1. 可以在程序运行过程中,操作这些对象.
      2. 可以解耦,提高程序的可扩展性.

获取Class对象的方式

  1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象.
    • 多用于配置文件,将类名定义在配置文件中,读取文件,加载类.
  2. 类名.class:通过类名的属性class获取.
    • 多用于参数的传递.
  3. 对象.getClass():在Object类中定义.
    • 多用于对象的获取字节码方式.

结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个.

Class对象的功能

获取功能

  1. 获取成员变量
    1. Field[] getFields():获取所有public修饰的成员变量
    2. Field getField(String name):获取指定名称的public修饰的成员变量.
    3. Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符.
    4. Field getDeclaredField(String name):获取指定名称的成员变量.
  2. 获取构造方法
    1. Constructor<?>[] getConstructors()
    2. Constructor<T> getConstructor(类<?>... parameterTypes)
    3. Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
    4. Constructor<?>[] getDeclaredConstructors()
  3. 获取成员方法
    1. Method[] getMethods()
    2. Method getMethod(String name, 类<?>... parameterTypes)
    3. Method[] getDeclaredMethods()
    4. Method getDeclaredMethod(String name, 类<?>... parameterTypes)
  4. 获取全类名
    • String getName()

Field:成员变量

  • 操作
    1. 设置值
      • void set(Object obj,Object value):第一个参数是设置的对象,第二个参数是值.
    2. 获取值
      • get(Object obj):参数表示获取的对象.
    3. 忽略权限修饰符的安全检查:setAccessible(true)暴力反射.

Constructor:构造方法

  • 创建对象
    • T newInstance(Object... initargs)
    • 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法.

Method:方法对象

  • 执行方法:Object invoke(Object obj,Object... args):第一个参数是要执行方法的对象.后面的参数是方法的参数.
  • 获取方法名称:String getName:获取方法名.
  • User对象
package Reflect_Demo;

public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name=‘" + name + ‘‘‘ +
                ", age=" + age +
                ‘}‘;
    }

    public void Sleep()
    {
        System.out.println("睡觉...");
    }
}

  • 反射案例
package Reflect_Demo;

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

public class demo1 {
    public static void main(String[] args) throws Exception {
        Class<User> userClass = User.class;
        Constructor<User> constructor = userClass.getConstructor(String.class, int.class);
        User user = constructor.newInstance("zhangsan", 15);
        Method sleep = userClass.getMethod("Sleep");
        sleep.invoke(user);
        Field name_Field = userClass.getDeclaredField("age");
        name_Field.setAccessible(true);
        System.out.println(user);
        name_Field.set(user,25);
        System.out.println(user);
    }
}

静态方法

静态代码块

    static {
        System.out.println("static_block");
    }

程序加载入内存之后,只会被执行一次.

静态方法

    public static void print_static()
    {
        System.out.println("static_print");
    }

可以使用类直接调用方法.

  • 静态代码定义
public class static_block {
    static {
        System.out.println("static_block");
    }
    public void print()
    {
        System.out.println("public_print");
    }
    public static void print_static()
    {
        System.out.println("static_print");
    }
}
  • 使用静态方法
    public static void main(String[] args) {
        try {
            Class.forName("Reflect_Demo.static_block");// 静态代码块
            static_block.print_static();// 静态方法
            static_block static_block = new static_block();
            static_block.print();// 公共方法

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

以上是关于Junit测试和反射的主要内容,如果未能解决你的问题,请参考以下文章

java Junit测试反射注解

Junit + 反射 + 注解(@interface)

Junit单元测试,反射,注解 annotation

Junit单元测试,反射,注解 annotation

Junit反射注解

Junit单元测试反射注解