国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Java】使用PowerMockito mock static方法/new對(duì)象/mock對(duì)象的public或private方法的簡(jiǎn)單示例

這篇具有很好參考價(jià)值的文章主要介紹了【Java】使用PowerMockito mock static方法/new對(duì)象/mock對(duì)象的public或private方法的簡(jiǎn)單示例。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1.針對(duì)方法打樁

1.1 打樁類的public static方法

測(cè)試用例中如果需要對(duì)public靜態(tài)方法的打樁,針對(duì)測(cè)試類增加注解@RunWith(PowerMockRunner.class)同時(shí)針對(duì)靜態(tài)方法所在的類增加注解@PrepareForTest({StaticMethod.class}),接著在測(cè)試用例調(diào)用方法之前增加

PowerMockito.mockStatic(StaticMethod.class);
PowerMockito.when(StaticMethod.getJavaVersion()).thenReturn(“1.8.0_92”); 或者用寫法
PowerMockito.doReturn(“1.8.0_92”).when(StaticMethod.class, “getJavaVersion”);
另外對(duì)PowerMockito的調(diào)用最好在產(chǎn)品類ProductClass對(duì)象new之前進(jìn)行,這樣保障一切模擬數(shù)據(jù)就緒后再進(jìn)行產(chǎn)品類的測(cè)試,保證測(cè)試用例一次性成功編寫的幾率。

import junit.framework.TestCase;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticMethod.class})
public class ProductClassTest extends TestCase {
    public void test_getCustomNameByVersion() {
        PowerMockito.mockStatic(StaticMethod.class);
        PowerMockito.when(StaticMethod.getJavaVersion()).thenReturn("1.8.0_92");
        ProductClass product = new ProductClass();
        assertEquals("18VersionSeries", product.getCustomNameByVersion());
    }
}

ProductClassTest.java
public class ProductClass {
    public String getCustomNameByVersion() {
        String javaVersion = StaticMethod.getJavaVersion();
        if(javaVersion.split("_")[0].contains("1.8")) {
            return "18VersionSeries";
        }
        else {
            return "OTHER";
        }
    }
}

ProductClass.java產(chǎn)品代碼調(diào)用其他類的靜態(tài)方法
public class StaticMethod {
    public static String getJavaVersion() {
        throw new RuntimeException();
    }
}

1.2 打樁類的private static方法

針對(duì)StaticMethod類中的private static方法打樁的時(shí)候,外部調(diào)用StaticMethod類的public方法仍然保持實(shí)際代碼的調(diào)用,因此在模擬private static方法之前,增加一行

PowerMockito.spy(StaticMethod.class);或者

PowerMockito.when(StaticMethod.getJavaVersion()).thenCallRealMethod();
以此保證除了具體的某個(gè)方法打樁,其他的方法保持照舊。另外,針對(duì)private方法,因?yàn)檎J菬o法直接訪問的,因此需要使用

下面的形式進(jìn)行調(diào)用。這里要注意一個(gè)事情,doReturn when 和 when thenReturn的差異,后者是雖然做了打樁但是實(shí)際的代碼還是會(huì)走一遍。

PowerMockito.doReturn(true).when(StaticMethod.class, “isProduct”);

import junit.framework.TestCase;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticMethod.class})
public class ProductClassTest extends TestCase {
    
    public void test_getCustomNameByVersion_product() throws Exception {
        PowerMockito.mockStatic(StaticMethod.class);
        PowerMockito.spy(StaticMethod.class);
        PowerMockito.doReturn(true).when(StaticMethod.class, "isProduct");

        ProductClass product = new ProductClass();
        assertEquals("18VersionSeries", product.getCustomNameByVersion());
    }
}

ProductClassTest.java測(cè)試用例
public class StaticMethod {
    public static String getJavaVersion() {
        if (isProduct()) {
            System.out.println("getJavaVersion()::product");
            return System.getProperty("java.version");
        }
        System.out.println("getJavaVersion()::test");
        throw new RuntimeException();
    }

    private static boolean isProduct() {
        if (System.getenv().containsKey("isProduct=false")) {
            System.out.println("isProduct()::false");
            return false;
        } else {
            System.out.println("isProduct()::true");
            return true;
        }
    }
}

StaticMethod.java
public class ProductClass {
    public String getCustomNameByVersion() {
        String javaVersion = StaticMethod.getJavaVersion();
        if(javaVersion.split("_")[0].contains("1.8")) {
            return "18VersionSeries";
        }
        else {
            return "OTHER";
        }
    }
}

ProductClass.java

1.3 打樁類的public方法實(shí)現(xiàn)部分中使用的new對(duì)象

如果要對(duì) StudentHandler.java的new對(duì)象進(jìn)行mock,那么需要把StudentHandler對(duì)象所在的類StudentMng放到 @PrepareForTest({StudentMng.class})

需要特別注意,在PrepareForTest中放的類在統(tǒng)計(jì)代碼覆蓋率的時(shí)候,覆蓋率是0。如果要針對(duì)該類進(jìn)行代碼測(cè)試覆蓋,那需要以其他的方式進(jìn)行模擬測(cè)試。

1 package training;
 2 
 3 import junit.framework.TestCase;
 4 import org.junit.runner.RunWith;
 5 import org.powermock.api.mockito.PowerMockito;
 6 import org.powermock.core.classloader.annotations.PrepareForTest;
 7 import org.powermock.modules.junit4.PowerMockRunner;
 8 
 9 
10 import java.util.ArrayList;
11 import java.util.List;
12 @RunWith(PowerMockRunner.class)
13 @PrepareForTest({StudentMng.class})
14 public class StudentMngTest extends TestCase {
15 
16 
17         public void test_getSpecifiedStudents() throws Exception {
18             StudentHandler handler = PowerMockito.mock(StudentHandler.class);
19             PowerMockito.when(handler.getAllStudents()).thenReturn(mockStudents());
20             PowerMockito.whenNew(StudentHandler.class).withNoArguments().thenReturn(handler);
21             StudentMng mng = new StudentMng();
22             assertEquals(1, mng.getSpecifiedStudents(10).size());
23     }
24 
25     private List<Student> mockStudents() {
26         List<Student> students = new ArrayList<>();
27         Student stu = new Student();
28         stu.setScore(new Score(80, 11));
29         students.add(stu);
30         return students;
31     }
32 }

StudentMngTest.java
1 package training;
 2 
 3 import java.util.List;
 4 
 5 public class StudentHandler {
 6     public StudentHandler() {
 7         System.out.println("invoke StudentHandler()");
 8         throw new RuntimeException();
 9     }
10     public List<Student> getAllStudents() {
11         System.out.println("invoke getAllStudents");
12         throw new RuntimeException();
13     }
14 }

StudentHandler.java 是一個(gè)不方便直接new的類
1 package training;
 2 
 3 public class Student {
 4     private String sno;
 5     private String name;
 6     private Score score = new Score(100, 1000);
 7 
 8     public String getName() {
 9         System.out.println("invoke getName");
10         return name;
11     }
12 
13     public void setName(String name) {
14         System.out.println("invoke setName");
15         this.name = name;
16     }
17 
18     public String getSno() {
19         System.out.println("invoke getSno");
20         return sno;
21     }
22 
23     public void setSno(String sno) {
24         System.out.println("invoke setSno");
25         this.sno = sno;
26     }
27 
28     public void setScore(Score score) {
29         System.out.println("invoke setScore");
30         this.score = score;
31     }
32 
33     public Score getScore() {
34         System.out.println("invoke getScore");
35         return score;
36     }
37 
38     public String getScoreRecord(int delta) {
39         System.out.println("invoke getScoreRecord");
40         return String.format("sno:%s,name:%s,value:%d,level:%d", sno, name, score.getValue() + delta, score.getLevel());
41     }
42 }

Student.java
1 package training;
 2 
 3 public class Score {
 4     private int value;
 5     private int level;
 6 
 7     public Score(int value, int level) {
 8         this.value = value;
 9         this.level =  level;
10     }
11 
12     public int getLevel() {
13         System.out.println("invoke getLevel");
14         return level;
15     }
16 
17     public void setLevel(int level) {
18         System.out.println("invoke setLevel");
19         this.level = level;
20     }
21 
22     public int getValue() {
23         System.out.println("invoke getValue");
24         return value;
25     }
26 
27     public void setValue(int value) {
28         System.out.println("invoke setValue");
29         this.value = value;
30     }
31 }

Score.java

1.4打樁類的public方法

2種方式,方式一:PowerMockito.mock方式,對(duì)應(yīng)StudentTest.java中的test_mock_public_method_powermock()測(cè)試用例
方式二:函數(shù)復(fù)寫override方式,對(duì)應(yīng)StudentTest.java中的test_mock_public_method_override()測(cè)試用例

兩種方式比較,方式一代碼看起來簡(jiǎn)潔。 方式二 測(cè)試用例運(yùn)行時(shí)間效率很高。

1 package training;
 2 
 3 import junit.framework.TestCase;
 4 import org.powermock.api.mockito.PowerMockito;
 5 
 6 public class StudentTest extends TestCase {
 7     public void test_mock_public_method_powermock()
 8     {
 9         Student stu = PowerMockito.mock(Student.class);
10         PowerMockito.when(stu.getName()).thenReturn("test_name");
11         PowerMockito.when(stu.getNewName()).thenCallRealMethod();
12         assertEquals("new_test_name", stu.getNewName());
13     }
14 
15     public void test_mock_public_method_override()
16     {
17         Student stu = new Student() {
18             @Override
19             public String getName() {
20                 return "test_name";
21             }
22         };
23         assertEquals("new_test_name", stu.getNewName());
24     }
25 }

StudentTest.java
1 package training;
 2 
 3 public class Student {
 4     private String name;
 5     
 6 
 7     public String getName() {
 8         System.out.println("invoke getName");
 9         throw new RuntimeException();
10 //        return name;
11     }
12 
13     public String getNewName() {
14         System.out.println("invoke getNewName");
15         return "new_" + getName();
16     }
17     
18 }

Student.java

1.5 打樁類的private方法

Student.java類中g(shù)etName方法為private的,因此需要使用PowerMockito.when(stu, “getName”).thenReturn(“test_name”); 方式進(jìn)行mock。

被模擬的Student類需要在測(cè)試用例test類的開頭增加以下兩行。

@RunWith(PowerMockRunner.class)
@PrepareForTest({Student.class})

1 package training;
 2 
 3 import junit.framework.TestCase;
 4 import org.junit.runner.RunWith;
 5 import org.powermock.api.mockito.PowerMockito;
 6 import org.powermock.core.classloader.annotations.PrepareForTest;
 7 import org.powermock.modules.junit4.PowerMockRunner;
 8 
 9 @RunWith(PowerMockRunner.class)
10 @PrepareForTest({Student.class})
11 public class StudentTest extends TestCase {
12     public void test_mock_public_method_powermock()
13     {
14         Student stu = PowerMockito.mock(Student.class);
15         try {
16             PowerMockito.when(stu, "getName").thenReturn("test_name");
17         } catch (Exception e) {
18             e.printStackTrace();
19         }
20         PowerMockito.when(stu.getNewName()).thenCallRealMethod();
21         assertEquals("new_test_name", stu.getNewName());
22     }
23 
24 }

StudentTest.java
1 package training;
 2 
 3 public class Student {
 4     private String sno;
 5     private String name;
 6     private Score score = new Score(100, 1000);
 7 
 8     private String getName() {
 9         System.out.println("invoke getName");
10         throw new RuntimeException();
11 //        return name;
12     }
13 
14     public String getNewName() {
15         System.out.println("invoke getNewName");
16         return "new_" + getName();
17     }
18 
19     public void setName(String name) {
20         System.out.println("invoke setName");
21         this.name = name;
22     }
23 
24     public String getSno() {
25         System.out.println("invoke getSno");
26         return sno;
27     }
28 
29     public void setSno(String sno) {
30         System.out.println("invoke setSno");
31         this.sno = sno;
32     }
33 
34     public void setScore(Score score) {
35         System.out.println("invoke setScore");
36         this.score = score;
37     }
38 
39     public Score getScore() {
40         System.out.println("invoke getScore");
41         return score;
42     }
43 
44     public String getScoreRecord(int delta) {
45         System.out.println("invoke getScoreRecord");
46         return String.format("sno:%s,name:%s,value:%d,level:%d", sno, name, score.getValue() + delta, score.getLevel());
47     }
48 }

Student.java

2.針對(duì)變量打樁

2.1 打樁類的private成員變量

方法一: Whitebox

來源StudentMngTest.java,關(guān)鍵模擬代碼如下,Whitebox.setInternalState(mng, “handler”, handler);打樁設(shè)置對(duì)象的私有成員變量。

PowerMockito.when(mng.getSpecifiedStudents(10)).thenCallRealMethod();控制調(diào)用實(shí)際的方法。

StudentMng mng = PowerMockito.mock(StudentMng.class); 控制StudentMng對(duì)象的初始化過程,保證在對(duì)象初始化的時(shí)候不去做StudentHandler成員變量的初始化。

public void test_getSpecifiedStudents() {
StudentHandler handler = PowerMockito.mock(StudentHandler.class);
PowerMockito.when(handler.getAllStudents()).thenReturn(mockStudents());
StudentMng mng = PowerMockito.mock(StudentMng.class);
Whitebox.setInternalState(mng, “handler”, handler);
PowerMockito.when(mng.getSpecifiedStudents(10)).thenCallRealMethod();
assertEquals(1, mng.getSpecifiedStudents(10).size());
}

package training;

import junit.framework.TestCase;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.reflect.Whitebox;

import java.util.ArrayList;
import java.util.List;

public class StudentMngTest extends TestCase {
    public void test_getSpecifiedStudents() {
        StudentHandler handler = PowerMockito.mock(StudentHandler.class);
        PowerMockito.when(handler.getAllStudents()).thenReturn(mockStudents());
        StudentMng mng = PowerMockito.mock(StudentMng.class);
        Whitebox.setInternalState(mng, "handler", handler);
        PowerMockito.when(mng.getSpecifiedStudents(10)).thenCallRealMethod();
        assertEquals(1, mng.getSpecifiedStudents(10).size());
    }

    private List<Student> mockStudents() {
        List<Student> students = new ArrayList<>();
        Student stu = new Student();
        stu.setScore(new Score(80, 11));
        students.add(stu);
        return students;
    }
}

StudentMngTest.java 打樁后 連初始化StudentMng對(duì)象的時(shí)候都模擬完成。
package training;

import java.util.List;

public class StudentHandler {
    public StudentHandler() {
        System.out.println("invoke StudentHandler()");
//        throw new RuntimeException();
    }
    public List<Student> getAllStudents() {
        System.out.println("invoke getAllStudents");
        throw new RuntimeException();
    }
}

StudentHandler.java
package training;

public class Student {
    private String sno;
    private String name;
    private Score score = new Score(100, 1000);

    public String getName() {
        System.out.println("invoke getName");
        return name;
    }

    public void setName(String name) {
        System.out.println("invoke setName");
        this.name = name;
    }

    public String getSno() {
        System.out.println("invoke getSno");
        return sno;
    }

    public void setSno(String sno) {
        System.out.println("invoke setSno");
        this.sno = sno;
    }

    public void setScore(Score score) {
        System.out.println("invoke setScore");
        this.score = score;
    }

    public Score getScore() {
        System.out.println("invoke getScore");
        return score;
    }

    public String getScoreRecord(int delta) {
        System.out.println("invoke getScoreRecord");
        return String.format("sno:%s,name:%s,value:%d,level:%d", sno, name, score.getValue() + delta, score.getLevel());
    }
}

Student.java
package training;

public class Score {
    private int value;
    private int level;

    public Score(int value, int level) {
        this.value = value;
        this.level =  level;
    }

    public int getLevel() {
        System.out.println("invoke getLevel");
        return level;
    }

    public void setLevel(int level) {
        System.out.println("invoke setLevel");
        this.level = level;
    }

    public int getValue() {
        System.out.println("invoke getValue");
        return value;
    }

    public void setValue(int value) {
        System.out.println("invoke setValue");
        this.value = value;
    }
}

Score.java

方法二(更加通用):用以下方式修改屬性的訪問權(quán)限,另外 @PrepareForTest({StudentMng.class}) 和 PowerMockito.whenNew(StudentHandler.class).withNoArguments().thenReturn(handler); 同時(shí)來達(dá)到mock new對(duì)象的目的。

Field handlerField = mng.getClass().getDeclaredField(“handler”);
handlerField.setAccessible(true);
handlerField.set(mng, handler);

1 package training;
 2 
 3 import junit.framework.TestCase;
 4 import org.junit.runner.RunWith;
 5 import org.powermock.api.mockito.PowerMockito;
 6 import org.powermock.core.classloader.annotations.PrepareForTest;
 7 import org.powermock.modules.junit4.PowerMockRunner;
 8 
 9 import java.lang.reflect.Field;
10 import java.util.ArrayList;
11 import java.util.List;
12 
13 @RunWith(PowerMockRunner.class)
14 @PrepareForTest({StudentMng.class})
15 public class StudentMngTest extends TestCase {
16     public void test_getSpecifiedStudents() throws Exception {
17         StudentHandler handler = PowerMockito.mock(StudentHandler.class);
18         PowerMockito.when(handler.getAllStudents()).thenReturn(mockStudents());
19         PowerMockito.whenNew(StudentHandler.class).withNoArguments().thenReturn(handler);
20         StudentMng mng = new StudentMng();
21         Field handlerField = mng.getClass().getDeclaredField("handler");
22         handlerField.setAccessible(true);
23         handlerField.set(mng, handler);
24         assertEquals(1, mng.getSpecifiedStudents(10).size());
25     }
26 
27     private List<Student> mockStudents() {
28         List<Student> students = new ArrayList<>();
29         Student stu = new Student();
30         stu.setScore(new Score(80, 11));
31         students.add(stu);
32         return students;
33     }
34 }

StudentMngTest.java

2.2 打樁類的public static變量或者private static變量

針對(duì)此類情況,建議對(duì)static變量賦值的部分進(jìn)行mock模擬,以此來達(dá)到模擬變量值得目的。

3.測(cè)試用例執(zhí)行效率簡(jiǎn)單說明

override方式模擬打樁方式的執(zhí)行測(cè)試用例時(shí)間消耗

< 不帶@RunWith(PowerMockRunner.class)和@PrepareForTest({StudentMng.class}) 方式的執(zhí)行測(cè)試用例時(shí)間消耗

< 只帶@RunWith(PowerMockRunner.class)方式的的執(zhí)行測(cè)試用例時(shí)間消耗

< 都帶@RunWith(PowerMockRunner.class)和@PrepareForTest({StudentMng.class}) 方式的的執(zhí)行測(cè)試用例時(shí)間消耗

關(guān)于代碼覆蓋率:在PrepareForTest中放的類在統(tǒng)計(jì)代碼覆蓋率的時(shí)候,覆蓋率是0。如果要針對(duì)該類進(jìn)行代碼測(cè)試覆蓋,

那需要以其他的方式進(jìn)行模擬測(cè)試。

關(guān)于編寫產(chǎn)品代碼:建議在編寫產(chǎn)品代碼的時(shí)候,盡量按照對(duì)象注入方式,同時(shí)減少靜態(tài)方法的實(shí)現(xiàn)方式,

以此也能增加代碼的靈活性,同時(shí)在給編寫測(cè)試用例也能帶來較大的便利。文章來源地址http://www.zghlxwxcb.cn/news/detail-821535.html

到了這里,關(guān)于【Java】使用PowerMockito mock static方法/new對(duì)象/mock對(duì)象的public或private方法的簡(jiǎn)單示例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包