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类的前提下
-
创建Student对象
-
分别为Student对象的name、age、score赋值
-
分别执行run、study方法
-
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, "漫画"); } }
注解
- 创建注解AllTest,并且AllTest注解只能修饰在类、接口上
- AllTest注解 保留周期为运行时期
- 通过反射实现:执行被AllTest注解修饰的那个类的所有方法
- 测试类验证
@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);
}
}