单测与反射与注解

Junit单测

单测是单元测试,是指对软件中的最小可测试单元进行检查和验证

参考代码

public class Student {
    private String name;
    private int age;
    private double score;
​
    public Student() {
    }
​
    public Student(String name, int age, double score) {
        // 姓名检查
        checkName(name);
        this.name = name;
​
        // 年龄检查
        checkAge(age);
        this.age = age;
        checkScore(score);
        this.score = score;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        // 改代码
        checkName(name);
        this.name = name;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        checkAge(age);
        this.age = age;
    }
​
    public double getScore() {
        return score;
    }
​
    public void setScore(double score) {
        checkScore(score);
        this.score = score;
    }
​
    private void checkName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("名字不能为空");
        }
        if (name.length() > 4 || name.length() < 2) {
            throw new IllegalArgumentException("名字必须2~4个字");
        }
    }
​
    private void checkAge(int age) {
        if (age > 100 || age < 15) {
            throw new IllegalArgumentException("年龄需要在15到100岁");
        }
    }
​
    private void checkScore(double score) {
        if (score > 100 || score < 0) {
            throw new IllegalArgumentException("成绩大于等于0,小于等于100");
        }
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}
 
package com.itheima.d1_junit;
​
import org.junit.Assert;
import org.junit.Test;
import org.junit.function.ThrowingRunnable;
​
public class StudentTest {
​
    /*
     * 分开写,每种情况分为一个测试方法
     * */
    @Test(expected = IllegalArgumentException.class)
    public void testException1() {
        // 1. 列举所有可能的异常创建学生对象情况 (name)
        Student s2 = new Student(null, 18, 100);
    }
​
    @Test(expected = IllegalArgumentException.class)
    public void testException2() {
        // 1. 列举所有可能的异常创建学生对象情况 (name)
        Student s3 = new Student("坤", 18, 100);
    }
​
    @Test(expected = IllegalArgumentException.class)
    public void testException3() {
        // 1. 列举所有可能的异常创建学生对象情况 (name)
        Student s4 = new Student("张三李四王五田七", 18, 100);
    }
​
    @Test
    public void testNormalStudentName() {
        // 要求:学生名字不能为空,名字必须2~4个字
​
        // 1. 列举所有可能已经创建出的学生对象
        Student s1 = new Student("张三", 18, 100);
​
        // 2. 使用Assert分别对创建的几个对象进行要求判断
        Assert.assertNotNull(s1.getName()); // 判断一个对象不为空
        int length = s1.getName().length();
        Assert.assertTrue((length >= 2 && length <= 4));
    }
​
​
    /*
     * 写在一个测试方法中
     * */
    @Test()
    public void testStudentName() {
        // 要求:学生名字不能为空,名字必须2~4个字
        /*
         * 第一部分:测试正常的创建
         * */
        // 1. 列举所有可能已经创建出的学生对象
        Student s1 = new Student("张三", 18, 100);
​
        // 2. 使用Assert分别对创建的几个对象进行要求判断
        Assert.assertNotNull(s1.getName()); // 判断一个对象不为空
        int length = s1.getName().length();
        Assert.assertTrue((length >= 2 && length <= 4));
​
        /*
         * 第二部分:测试异常的创建
         * */
        Assert.assertThrows(IllegalArgumentException.class, () -> {
            new Student(null, 18, 100);
        });
        Assert.assertThrows(IllegalArgumentException.class, () -> {
            new Student("坤", 18, 100);
        });
        Assert.assertThrows(IllegalArgumentException.class, () -> {
            new Student("张三李四王五田七", 18, 100);
        });
​
    }
​
    @Test
    public void testStudentAge() {
        // 年龄是15到100岁
        Student s1 = new Student("张三", 20, 100);
​
        // 验证正常写法下,年龄是否有问题
        Assert.assertTrue(s1.getAge() > 15 && s1.getAge() < 100);
​
        // 验证创建不符合年龄要求的对象,
        // 是否会抛出预期的IllegalArgumentException异常
        Assert.assertThrows(IllegalArgumentException.class, new ThrowingRunnable() {
            @Override
            public void run() throws Throwable {
                new Student("张三", 10, 100);
            }
        });
​
        Assert.assertThrows(IllegalArgumentException.class,
                () -> new Student("张三", 200, 100));
    }
​
​
    @Test
    public void testStudentScore() {
        // 成绩大于等于0,小于等于100
        Student s1 = new Student("张三", 20, 80);
​
        // 验证正常写法下,年龄是否有问题
        Assert.assertTrue(s1.getScore() >= 0 && s1.getScore() <= 100);
​
        // 验证创建不符合年龄要求的对象,
        // 是否会抛出预期的IllegalArgumentException异常
        Assert.assertThrows(IllegalArgumentException.class, new ThrowingRunnable() {
            @Override
            public void run() throws Throwable {
                new Student("张三", 50, -100);
            }
        });
​
        Assert.assertThrows(IllegalArgumentException.class,
                () -> new Student("张三", 50, 300));
​
    }
}

@Before & @After

public class JunitTest3 {
    private FileInputStream is;
​
    @Before
    public void testBefore() throws FileNotFoundException {
        // junit测试中,相对路径是从模块下的src目录开始
        is = new FileInputStream("src\com\itheima\qqq.txt");
    }
​
    @After
    public void testAfter() throws IOException {
        is.close();
    }
​
    @Test
    public void test1() throws IOException {
        int len;
        while ((len = is.read()) != -1) {
            System.out.print((char) len);
        }
    }
​
    @Test
    public void test2() throws IOException {
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            String s = new String(buffer, 0, len);
            System.out.println(s);
        }
    }
​
​
    @Test
    public void test3() {
        System.out.println("我啥也没干");
    }
}

反射的第一个框架

public class objectFrame {
    public static void saveObjectToFile(Object obj) throws IllegalAccessException, IOException {
        Properties properties = new Properties();
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //禁用权限检测
            field.setAccessible(true);
            //获取变量名
            String name = field.getName();
            String value = String.valueOf(field.get(obj));
            properties.setProperty(name,value);
        }
        String fileName =clazz.getSimpleName()+ "_store.properties";
        properties.store(new FileWriter(fileName),null);
    }
}
//使用反射技术:设计一个保存对象的简易框架
public class objectFrameTest {
    public static void main(String[] args) throws IOException, IllegalAccessException {
        Cat c = new Cat("喵喵喵", 3);
       objectFrame.saveObjectToFile(c);
        Student s = new Student("张的",3);
        objectFrame.saveObjectToFile(s);
    }
}
创建反射的三种方式
Class c1 = Student.class; System.out.println(c1.getName()); //获取全类名 System.out.println(c1.getSimpleName()); //获取简单类名    
Class c2 = Class.forName("com.itheima.d2_reflect.Student");
    System.out.println(c1 == c2); //true
    
    Student s = new Student();
    Class c3 = s.getClass();
    System.out.println(c2 == c3); //true
使用反射技术做到,不修改Student类的前提下
  1. 创建Student对象

  2. 分别为Student对象的name、age、score赋值

  3. 分别执行run、study方法

  1. public class Student {
        private String name;
        private int age;
        private double score;
    
        private Student() {
        }
    ​
        private void run() {
        System.out.println("学生下课干饭跑得飞快");
        }
    ​
        private void study(String bookName) {
        System.out.println("学生在看" + bookName + "书");
        }
    ​
        @Override
        public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", score=" + score +
                '}';
        }
    
    }
    
    public class StudentTest {
        @Test
        public void test1() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
            Class clazz = Student.class;
            Constructor declaredConstructor = clazz.getDeclaredConstructor();
            declaredConstructor.setAccessible(true);
            Student student = declaredConstructor.newInstance();
            Field name = clazz.getDeclaredField("name");
            name.setAccessible(true);
            name.set(student, "小明");
            Field age = clazz.getDeclaredField("age");
            age.setAccessible(true);
            age.set(student, 3);
            System.out.println(student);
            Method run = clazz.getDeclaredMethod("run");
            run.setAccessible(true);
            run.invoke(student);
            Method study = clazz.getDeclaredMethod("study", String.class);
            study.setAccessible(true);
            study.invoke(student, "漫画");
        }
    }

    注解

    1. 创建注解AllTest,并且AllTest注解只能修饰在类、接口上
    2. AllTest注解 保留周期为运行时期
    3. 通过反射实现:执行被AllTest注解修饰的那个类的所有方法
    4. 测试类验证
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AllTest {

}

public class AllTestdemo {
    @AllTest
    public void test1() {
        System.out.println("方法1执行了");
    }

    @AllTest
    public void test2() {
        System.out.println(1 + 2);
    }
}

public class AllTestdemo {
    @AllTest
    public void test1() {
        System.out.println("方法1执行了");
    }

    @AllTest
    public void test2() {
        System.out.println(1 + 2);
    }
}
反射和properties综合

Person类如下

public class Person {
    private String username;
    private String password;
    private String name;
    private int age;
​
    private Person(String username, String password, String name, int age) {
        this.username = username;
        this.password = password;
        this.name = name;
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "Person{" +
                "username='" + username + ''' +
                ", password='" + password + ''' +
                ", name='" + name + ''' +
                ", age=" + age +
              '}';
    }
}

在不修改Person类的前提下,读取conf.properties文件中的内容,使用反射技术创建对应的对象并赋值,最终打印对象信息

conf.properties文件内容参考

(注意className的内容写类的全限定名,可以不和参考内容完全一致)

 
className=com.itheima.d2_reflect.demo1.Person
username=zs
password=123456
name=zhangsan
age=18

程序运行结果参考:

 
通过配置文件创建了对象,并赋值结果是:Person{username='zs', password='123456', name='zhangsan', age=18}
 
public class Test {
@org.junit.Test
    public void test() throws IOException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException {
    Properties properties = new Properties();
    properties.load(new FileReader("D:\develop\code\javase\day16\src\com\it\Demo4\conf.properties"));
    String username = properties.getProperty("username");
    String password = properties.getProperty("password");
    String name = properties.getProperty("name");
    int age = Integer.parseInt(properties.getProperty("age"));
    String className = properties.getProperty("className");
    Class personClass = Class.forName(className);
    Constructor<Peoson> constructor = personClass.
            getDeclaredConstructor(String.class, String.class, String.class, int.class);
    constructor.setAccessible(true);
    Peoson peoson = constructor.newInstance(username, password, name, age);
    System.out.println(peoson);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值