[TOC]
Junit測試
用junit測試可以不用每次都去寫方法,注釋方法去測試,提高了效率,
如何測試呢,看代碼:
這個是之前的小方法,用于測試
package com.ly.day01;
public class Ly {
public void sayName(){
System.out.println("this gay is ly");
}
}
這個是用來進行junit測試的測試類:
package test;
import org.junit.Test;
import com.ly.day01.Ly;
public class testLy {
@Test
public void testSayLy(){
new Ly().sayName();
}
}
其實差別就是多加了一個@Test注解,并且在運行的時候選擇 run as junitTest。
如果方法沒錯,那么就會出現(xiàn)綠條:
而如果測試失敗了,就會出現(xiàn)
注解@before 和 @after
在主體類中新增一個方法:
package com.ly.day01;
public class Ly {
public void sayName(){
System.out.println("this gay is ly");
}
public void setName(String newName){
System.out.println("gay, your new name is "+newName);
}
}
同樣的 我們在測試類中新增一個測試方法:
@Test
public void testSetName(){
new Ly().setName("lht");
}
值得注意的是,一個測試類里面如果有多個測試方法,而我們要一起運行的話,我們可以在
點擊整個類運行 run as junitTest
但是在運行之前我們新增2個注解方法:
@Before
public void before(){
System.out.println("this gay run before the function");
}
@After
public void after(){
System.out.println("this gay run after the function");
}
運行之后 我們會發(fā)現(xiàn):
this gay run before the function
this gay is ly
this gay run after the function
this gay run before the function
gay, your new name is lht
this gay run after the function
注解@Before,@After 在每個運行方法之前都會先運行一次
@BeforeClass 和 @AfterClass
同樣的 我們在測試類中新增兩個測試方法,注意他們要是靜態(tài)的
@BeforeClass
public static void beforeClass(){
System.out.println("before class");
}
@AfterClass
public static void afterClass(){
System.out.println("after class");
}
運行一次,結果為:
before class
this gay run before the function
this gay is ly
this gay run after the function
this gay run before the function
gay, your new name is lht
this gay run after the function
after class
我們可以發(fā)現(xiàn) * @after和@before 在每個測試方法前后都會運行一次,而
@BeforeClass 和 @AfterClass 則是和類掛鉤,只運行一次*
而我們注意到,其實我們在上述的每個測試方法里面都會去實例化一個Ly對象,那么其實我們可以抽離出來,如下:
package test;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.ly.day01.Ly;
public class testLy {
private static Ly mLy;
@BeforeClass
public static void beforeClass(){
System.out.println("before class");
mLy=new Ly();
}
@AfterClass
public static void afterClass(){
System.out.println("after class");
mLy=null;
}
@Before
public void before(){
System.out.println("this gay run before the function");
}
@After
public void after(){
System.out.println("this gay run after the function");
}
@Test
public void testSayLy(){
mLy.sayName();
}
@Test
public void testSetName(){
mLy.setName("lht");
}
}
他們的結果是一樣,
而在開發(fā)中 這兩對注解我們可以更加實用的去用。
斷言 Assert
上面我們只是測了方法是否可以運行,而如果方法是可以運行的,但是我們又不知道方法運行得對不對,那怎么辦呢,我們可以用Assert斷言來做判斷,
首先我們在Ly類中加入方法,返回值為String:
public String getName(){
return "Ly";
}
而在測試類中加入測試方法:
@Test
public void testGetName(){
Assert.assertEquals("Ly", mLy.getName());
}
我們可以看到Assert.assertEquals中有兩個值,一個是我們期望得到的值,一個是方法的返回數據,其實就很像Android中的TextUtils.equals(String str,String str);很顯然,兩者equals的時候方法通過,綠條;反之黃條。
相應的Assert還有其他的assertXXXX方法,但是用法大同小異。
拿map數據的兩種方式:
/**
* 取map里面的值的方法 傳統(tǒng)方法1
*/
@Test
public void getMapValue1() {
/*
* HashMap是無序的如果我們需要做有序存儲,最好用 LinkedHashMap
*/
Map map = new LinkedHashMap();
map.put(5, "--1");
map.put(2, "--2");
map.put(3, "--3");
Set set = map.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
int key = (Integer) it.next();
String val = (String) map.get(key);
System.out.println(key + "---" + val);
}
}
/**
* 取map數據的傳統(tǒng)方法2
*/
@Test
public void getMapValue2() {
/*
* HashMap是無序的如果我們需要做有序存儲,最好用 LinkedHashMap
*/
Map map = new LinkedHashMap();
map.put(5, "--1");
map.put(2, "--2");
map.put(3, "--3");
Set set = map.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Map.Entry entry = (Entry) it.next();
int key = (Integer) entry.getKey();
String val = (String) entry.getValue();
System.out.println(key + "---" + val);
}
}
其實上面的方法還可以用foreach的方法再改進
枚舉
package com.ly.day02;
public enum Grade {
// A, B, C;
// A("good"), B("just so so"), C("bad");
A("good") {
@Override
public void attitude() {
System.out.println("表揚");
}
},
B("just so so") {
@Override
public void attitude() {
System.out.println("冷漠臉");
}
},
C("bad") {
@Override
public void attitude() {
System.out.println("批評");
}
};
// 其實枚舉就類似于:
// public static final Grade A=new Grade();
// 所以枚舉類其實就是一個類,我們可以在方法里面加字段,加構造方法:
private String Evaluation;
private Grade(String evaluation) {
Evaluation = evaluation;
}
public String getEvaluation() {
return Evaluation;
}
public void setEvaluation(String evaluation) {
Evaluation = evaluation;
}
/**
* 加入了上述構造方法和getset后,我們之前定義的枚舉ABCD爆紅了,為什么? 因為他們其實就是public static final Grade
* A=new Grade(); 我們加了構造方法,替換了之前的無參構造方法,所以就爆紅了,我們可以修改為: A("good"),
* B("just so so"), C("bad");
*/
/**
* 如果每個枚舉都要做不同的事情的時候,那么我們可以定義一個抽象方法,比如: 而加入了抽象方法之后,我們每個枚舉類型都要進行實現(xiàn): A("good")
* {
*
* @Override public void attitude() { System.out.println("表揚");
*
* } }, B("just so so"){
* @Override public void attitude() { System.out.println("冷漠臉");
*
* } }, C("bad"){
* @Override public void attitude() { System.out.println("批評");
*
* } };
*/
public abstract void attitude();
}
反射技術
拿到反射class 的三種方法:
package com.ly.day02.reflect;
public class PersonReflect {
public static void main(String[] args) throws ClassNotFoundException {
// 1
Class clazz=Class.forName("com.ly.day02.reflect.Person");
// 2
Class clazz1=new Person().getClass();
// 3
Class clazz2=Person.class;
}
}
拿到類的構造方法(public)
package com.ly.day02.reflect;
public class Person {
public String name="this is the name";
public String pass="this is the pass";
public Person(){
super();
}
public Person(String name, String pass) {
super();
this.name = name;
this.pass = pass;
}
}
我們可以這么拿Person類的構造方法:
- 這里拿的是無參的構造方法:
@Test
public void TestDef() throws Exception {
Class clazz = Class.forName("com.ly.day02.reflect.Person");
Constructor constructor = clazz.getConstructor(null);
Person person = (Person) constructor.newInstance(null);
System.out.println(person.name);
System.out.println(person.pass);
}
- 這里拿的是有參的構造方法:
@Test
public void test() throws Exception {
Class clazz = Class.forName("com.ly.day02.reflect.Person");
Constructor constructor = clazz.getConstructor(String.class,
String.class);
Person person = (Person) constructor.newInstance("Ly", "password");
System.out.println(person.name);
System.out.println(person.pass);
}
輸出結果分別為:
訪問私有的:
getDeclaredConstructor可以返回指定參數的構造函數,而getConstructor只能放回指定參數的public的構造函數區(qū)別只是后者只可以返回公有的構造函數
@Test
public void test() throws Exception {
Class clazz = Class.forName("com.ly.day02.reflect.Person");
// 用這個方法來獲取非public的構造方法
Constructor constructor = clazz.getDeclaredConstructor(String.class,
String.class);
// 暴力破解
constructor.setAccessible(true);
Person person = (Person) constructor.newInstance("Ly", "password");
System.out.println(person.name);
System.out.println(person.pass);
}
另外一種獲取類的方法,需要對象類里面有一個無參的構造方法:
@Test
public void testAgain() throws Exception {
Class clazz = Class.forName("com.ly.day02.reflect.Person");
Person person = (Person) clazz.newInstance();
System.out.println(person.toString());
}