10.Java-Junit&注解&枚举

一、Junit

属于白盒测试

1. 普通测试麻烦说明

  • 没有使用junit的时候缺点:
    * 1.测试一定走main方法,是程序的入口,main方法的格式必须不能写错
    * 2.要是在同一个main方法中测试的话,那么不需要测试的东西必须注释掉。
    * 3.测试逻辑如果分开,需要定义多个测试类,麻烦
    * 4.业务逻辑和测试代码,都混淆了

1. 代码

package com.fj.Junit.Junit;

public class Calculator {
    //加法
    public int add(int a, int b) {
        return a + b;
    }

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

2. 调用代码

package com.fj.Junit.Junit;

public class Demo01 {
    public static void main(String[] args) {

        /*****************************************************************
         * 没有使用junit的时候缺点:
         * 1.测试一定走main方法,是程序的入口,main方法的格式必须不能写错
         * 2.要是在同一个main方法中测试的话,那么不需要测试的东西必须注释掉。
         * 3.测试逻辑如果分开,需要定义多个测试类,麻烦
         * 4.业务逻辑和测试代码,都混淆了
         * ***************************************************************
         */
        //测试加法
        Calculator cal = new Calculator();
        int result = cal.add(10,20);
        System.out.println(result);
        int result1 = cal.sub(20,10);
        System.out.println(result1);
    }

}


2. Junit 的使用

1.使用说明

  • 【1】一般测试和业务做一个分离,分离为不同的包:建议起名:公司域名倒着写+test
  • 【2】测试类的名字: ****Test—>见名知意
  • 【3】测试方法的定义->这个方法可以独立运行,不依托与main方法
  • 名字:testAdd() testSub() 见名知意
  • 参数:无参
  • 返回值:无返回值
  • 【4】测试方法定义完以后,不能直接就独立运行,必须要在方法前加入一个注解:@Test
  • 【5】导入Junit的依赖环境:
    在这里插入图片描述
  • 【6】代码演示

```java
package com.fj.Junit.Junit;

import org.junit.Test;

/**
 * 测试方法
 */
public class CalculatorTest {
    @Test
    public void testAdd() {
        System.out.println("测试add方法");
        Calculator cal = new Calculator();
        int result = cal.add(10, 20);
        System.out.println(result);

    }
    @Test
    public void testSub() {
        System.out.println("测试Sub方法");
        Calculator cal = new Calculator();
        int result = cal.sub(10, 20);
        System.out.println(result);
    }
}

  • 【7】绿色正常,红色异常
    在这里插入图片描述
  • 【8】即使出现绿色接口,也不代表代码,通过,可能出现逻辑错误
  • 【9】加入断言Assert.assertEquals:预测结果,判断一下我预测的结果和实际的结果是否一致
    1. 如果疏忽吧加法携程成减法,如下代码
package com.fj.Junit.Junit;

public class Calculator {
    //加法

    public int add(int a, int b) {
        //int num = 6 / 0;
        return a - b;
    }

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

  1. 测试中加入断言,如下代码
package com.fj.Junit.Junit;

import org.junit.Assert;
import org.junit.Test;

/**
 * 测试方法
 */
public class CalculatorTest {
    @Test
    public void testAdd() {
        System.out.println("测试add方法");
        Calculator cal = new Calculator();
        int result = cal.add(10, 30);
       // System.out.println(result); //程序的运行结果可以不关注
        //加入断言:预测结果,判断一下我预测的结果和实际的结果是否一致:
        Assert.assertEquals(40,result);

    }
    @Test
    public void testSub() {
        System.out.println("测试Sub方法");
        Calculator cal = new Calculator();
        int result = cal.sub(10, 20);
        System.out.println(result);
    }
}

  1. 返回结果:
测试add方法

java.lang.AssertionError: 
Expected :40
Actual   :-20
<Click to see difference>


	at org.junit.Assert.fail(Assert.java:89)
	at org.junit.Assert.failNotEquals(Assert.java:835)
	at org.junit.Assert.assertEquals(Assert.java:647)
	at org.junit.Assert.assertEquals(Assert.java:633)
	at com.fj.Junit.Junit.CalculatorTest.testAdd(CalculatorTest.java:17)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)


Process finished with exit code -1

二、注解

1. 注解介绍

  • 【1】 @Before: 在测试方法之间执行 ,一般会在@Before 修饰的那个方法中加入一些申请资源的代码:申请数据库资源,申请io资源,申请网络资源…
  • 【2】@After: 在方法执行之后执行,一般会在@After修饰的那个方法中加入释放资源的代码:释放数据库资源,释放io资源,释放网络资源…
  • 【3】@Override:限定重写父类方法,该注解只能用于方法。@Override的作用:限定重写的方法,只要重写方法有问题,就有错误提示
  • 【4】@Deprecated:用于表示所修饰的元素(类,方法,构造器,属性等)已过时。通常是因为所修饰的结构危险或存在更好的选择。@Deprecated作用:在方法前加入@Deprecated,这个方法就会变成废弃、过期、过时方法
  • 【5】@SuppressWarnings:抑制编辑器警告@SuppressWarnings("unused") int age =10;
  • 【6】代码演示
package com.fj.Junit.Junit;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * 测试方法
 */
public class CalculatorTest {
    @Before
    public void init() {
        System.out.println("方法执行开始了..........");
    }
    @After
    public void close(){
        System.out.println("方法执行结束了..........");
    }

    @Test
    public void testAdd() {
        System.out.println("测试add方法");
        Calculator cal = new Calculator();
        int result = cal.add(10, 30);
        // System.out.println(result); //程序的运行结果可以不关注
        //加入断言:预测结果,判断一下我预测的结果和实际的结果是否一致:
        Assert.assertEquals(40, result);

    }

    @Test
    public void testSub() {
        System.out.println("测试Sub方法");
        Calculator cal = new Calculator();
        int result = cal.sub(10, 20);
        // System.out.println(result);
    }
}

  • 结果:
方法执行开始了..........
测试add方法
方法执行结束了..........

Process finished with exit code 0
  • 【7】注意
    在这里插入图片描述

2. 生成JvaDoc文档注解

  • Tools-> Generate JAVADoc…在这里插入图片描述
  • 定义参数:其他参数:-encoding utf-8 -charset utf-8
    在这里插入图片描述

3. 自定义注解

【1】自定义注解使用很少,一般情况下都是现成的
【2】如何使用自定义注解:
定义注解的声明使用关键字是:@interface

package com.fj.Junit.anno;

/**
 * 声明注解
 */
public @interface MyAnnotation {
}

【3】注解的内部:

  1. 以@SuppressWarnings为例,发现内部:String[] value();是属性还是方法?
    答案:看上去是无参数方法,实际理解为一个成员变量,一个属性。
    无参数方法名字—>成员变量的名字
    无参数方法的返回值—>成员变量的类型
    这个参数叫 配置参数
    无参数方法的类型:基本数据类型(八种),String,枚举,注解类型,还可以是以上类型所对应的数组
    ps:如果只有一个成员变量的话,就起名叫value
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

【4】使用注解

  • 使用注解的话,如果你定义了配置参数,就必须给赋值操作
  • 如果只有一个参数,并且这个参数的名字为value的话,value=可以不写
  • 如果你给配置参数设置了默认值,使用的时候无需传值
  • 一个注解的内部可以不定义配置参数的
  • 内部没有定义配置参数的注解->标记
  • 内部定义配置参数的注解->元数据
  1. 定义注解代码:
package com.fj.Junit.anno;

/**
 * 声明注解
 */
public @interface MyAnnotation {
    //
    String[] value();
}

  1. 使用注解代码
package com.fj.Junit.anno;

/**
 * @author fj 
 */
@MyAnnotation(value = {"dd","ee","ddd"})
public class Person {
  
}


  1. 使用注解,value=不写
package com.fj.Junit.anno;

/**
 * @author fj 
 */
@MyAnnotation({"dd","ee","ddd"})
public class Person {
  
}

  1. 配置参数默认值代码
package com.fj.Junit.anno;

public @interface MyAnnotation2 {
    String value() default "abc";
}

  1. 配置参数默认值调用代码
package com.fj.Junit.anno;
package com.fj.Junit.anno;

/**
 * @author fj 
 */
@MyAnnotation({"dd","ee","ddd"})
@MyAnnotation2
public class Person {
  
}

  1. 内部不定义配置参数的注解
package com.fj.Junit.anno;

public @interface MyAnnotation3 {
}

4. 元注解

元注解就是用于修饰其他注解的注解
举例:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {

JDK5.0提供了四种元注解:Retention,Target,Documented,Inherited
五重注解说明:引用Gene Xu的五种注解博客,点击跳转

三、枚举

1. JDK1.5之前枚举类说明

在java中,类的对象是有限的,确定的。这个类我们可以定义为枚举类。
枚举类

package com.fj.Junit.test_enum;

/**
 * 枚举类
 */
public class Season {
    public String getSeasonName() {
        return seasonName;
    }

    public void setSeasonName(String seasonName) {
        this.seasonName = seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    public void setSeasonDesc(String seasonDesc) {
        this.seasonDesc = seasonDesc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }

    //属性
    private String seasonName;//季节名称
    private String seasonDesc;//季节描述

    //利用构造器对属性进行赋值
    //私有化
    private Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //提供枚举类的有限的确定的对象:
    public static final Season SPRING = new Season("春天", "春暖花开");
    public static final Season SUMMER = new Season("夏天", "烈日洋洋");
    public static final Season AUTUMN = new Season("秋天", "硕果累累");
    public static final Season WINTER = new Season("冬天", "冰天雪地");


}

调用枚举类:

package com.fj.Junit.test_enum;

public class Demo01 {
    public static void main(String[] args) {
        Season summer = Season.SUMMER;
        System.out.println(summer);
        System.out.println(summer.getSeasonName());
    }
}

2. JDK1.5之后枚举类

  • 确定的对象–> enum枚举类要求对象(常量)必须放在最开始的位置,多个对象之间用,隔开,最后一个用;
  • 用enum修饰
  • enum关键字对应的枚举类的上次父类实:java.lang.Enum
  • 但是我们自定义的枚举类的上层父类,是objetc
package com.fj.Junit.test_enum2;

/**
 * 枚举类
 */
public enum Season {
    //确定的对象--> enum枚举类要求对象(常量)必须防砸最开始的位置,多个对象之间用,隔开,最后一个用;
    SPRING("春天", "春暖花开"),
    SUMMER("夏天", "烈日洋洋"),
    AUTUMN("秋天", "硕果累累"),
    WINTER("冬天", "冰天雪地");

    public String getSeasonName() {
        return seasonName;
    }

    public void setSeasonName(String seasonName) {
        this.seasonName = seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    public void setSeasonDesc(String seasonDesc) {
        this.seasonDesc = seasonDesc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }

    //属性
    private String seasonName;//季节名称
    private String seasonDesc;//季节描述

    //利用构造器对属性进行赋值
    //私有化
    private Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }


}

调用枚举类

package com.fj.Junit.test_enum2;

public class Demo01 {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println(spring);
        //enum关键字对应的枚举类的上次父类实:java.lang.Enum
        //但是我们自定义的枚举类的上层父类,是objetc
        System.out.println(Season.class.getSuperclass().getName());
    }
}

3. 空枚举类

为什么这么简单:因为这个枚举类底层没有属性,构造器,toSting,get方法,然后按理来说应该写为SPRINT() ,现在脸()可以省略,就变成SPRINT

package com.fj.Junit.test_enum3;

/**
 * 枚举类
 */
public enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER;
}

4. Enum方法

package com.fj.Junit.test_enum3;

public class Demo01 {
    public static void main(String[] args) {
        //用enum关键字创建的season枚举类上面的父类实:java.lang.Enum,常用方法子类Season可以直接拿过来使用
        //toString() 获取对象的名字
        Season autumn = Season.AUTUMN;
        System.out.println(autumn);
        System.out.println("======================");
        //values 返回枚举类对象的数组
        Season[] values = Season.values();
        for(Season s:values){
            System.out.println(s);
        }
        System.out.println("======================");
        //valueOf  注意:对象的名字必须正确。
        //通过对象名字获取这个枚举对象
        Season autumn1 = Season.valueOf("AUTUMN");
        System.out.println(autumn1);
    }
}

5. 枚举类实现接口

1.枚举类实现接口

【1】定义一个接口

package com.fj.Junit.test_enum4;

/**
 * 接口
 */
public interface Demo01 {
    void Show();
}

【2】枚举类实现这个接口

package com.fj.Junit.test_enum4;

/**
 * 枚举类
 */
public enum Season implements Demo01 {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER;

    @Override
    public void Show() {
        System.out.println("Show");
    }
}

【3】测试类:
所有的枚举对象,调用这个show方法的时候走得都是同一个方法,结构也是相同的

package com.fj.Junit.test_enum4;

public class Test {
    public static void main(String[] args) {
        Season autumn = Season.AUTUMN;
        autumn.Show();
        Season summer = Season.SUMMER;
        summer.Show();
    }
}

结果:

Show
Show

Process finished with exit code 0

2. 枚举类实现接口各自实现接口方法

【1】接口类

package com.fj.Junit.test_enum4;

/**
 * 接口
 */
public interface Demo01 {
    void Show();
}

【2】枚举类

package com.fj.Junit.test_enum4;

/**
 * 枚举类
 */
public enum Season implements Demo01 {
    SPRING{
        @Override
        public void Show() {
            System.out.println("这是春天");;
        }
    },
    SUMMER{
        @Override
        public void Show() {
            System.out.println("这是夏天");
        }
    },
    AUTUMN{
        @Override
        public void Show() {
            System.out.println("这是秋天");
        }
    },
    WINTER{
        @Override
        public void Show() {
            System.out.println("这是冬天");
        }
    };

/*    @Override
    public void Show() {
        System.out.println("Show");
    }*/
}

【3】 测试类

package com.fj.Junit.test_enum4;

public class Test {
    public static void main(String[] args) {
        Season autumn = Season.AUTUMN;
        autumn.Show();
        Season summer = Season.SUMMER;
        summer.Show();
    }
}

结果:

这是秋天
这是夏天

Process finished with exit code 0

6. 枚举的应用

1. 应用1

  1. 枚举类
package com.fj.Junit.test_enum5;

public enum Gender {,;
}

  1. 普通类
package com.fj.Junit.test_enum5;

public class Person {
    //属性
    private int age;
    private String name;
    private Gender sex;

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", sex=" + sex +
                '}';
    }
}

  1. 测试类
package com.fj.Junit.test_enum5;

public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        p.setAge(19);
        p.setName("kk");
        p.setSex(Gender.);//传入枚举类对象-->在入口处对参数进行了限制
        System.out.println(p);
    }
}

结果:

Person{age=19, name='kk', sex=}

Process finished with exit code 0

2. 应用2:

  1. 枚举类:
package com.fj.Junit.test_enum5;

public enum Gender {,;
}

  1. 测试类
package com.fj.Junit.test_enum5;

public class Demo02 {
    public static void main(String[] args) {
        Gender sex = Gender.;
        //switch 后面()中可以传入枚举类型
        //switch 后面() :int,short,byte,char,String,枚举类型
        switch (sex){
            case:
                System.out.println("女");
                break;
            case:
                System.out.println("男");
                break;
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值