<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          有了它(powerMocker)再也不怕單元測(cè)試不達(dá)標(biāo)了!

          共 14945字,需瀏覽 30分鐘

           ·

          2021-09-27 03:01

          ????關(guān)注后回復(fù) “進(jìn)群” ,拉你進(jìn)程序員交流群????

          作者丨java金融

          來源丨java金融

          為什么要寫單元測(cè)試

          • 優(yōu)點(diǎn):?jiǎn)卧獪y(cè)試可以減少bug率,提升代碼的質(zhì)量。還可以通過單元測(cè)試來熟悉業(yè)務(wù)。
          • 公司硬性要求:有些公司可能還會(huì)強(qiáng)制要求,每次新增代碼、或者變更代碼單測(cè)覆蓋率要達(dá)到多少比例才能申請(qǐng)代碼合并請(qǐng)求。

          選擇哪個(gè)單元測(cè)試框架

          目前應(yīng)用比較普遍的java單元測(cè)試工具junit4+Mock(Mockito、jmock、EasyMock、powermock)。為什么會(huì)選powermock?
             在做單元測(cè)試的時(shí)候,我們會(huì)發(fā)現(xiàn)我們要測(cè)試的方法會(huì)有很多外部依賴的對(duì)象或者一些其他服務(wù)的調(diào)用比如說(發(fā)送郵件,網(wǎng)絡(luò)通訊,soa調(diào)用)。而我們沒法控制這些外部依賴的對(duì)象。為了解決這個(gè)問題,我們需要用到Mock來模擬這些外部依賴的對(duì)象,從而控制它們。只關(guān)心我們自己的業(yè)務(wù)邏輯是否正確。而這時(shí)powermock就起作用了,它不僅可以mock外部的依賴,還可以mock私有方法、final方法,總之它的功能很強(qiáng)大。

          什么是powerMocker

          PowerMock是一個(gè)框架,它以更強(qiáng)大的功能擴(kuò)展了其他模擬庫(kù),例如EasyMock。PowerMock使用自定義的類加載器和字節(jié)碼操作來模擬靜態(tài)方法,構(gòu)造函數(shù), 最終類和方法,私有方法,刪除靜態(tài)初始化程序等。通過使用自定義類加載器,無需對(duì)IDE或持續(xù)集成服務(wù)器進(jìn)行任何更改,從而簡(jiǎn)化了采用過程。熟悉受支持的模擬框架的開發(fā)人員會(huì)發(fā)現(xiàn)PowerMock易于使用,因?yàn)檎麄€(gè)期望API都是相同的, 無論是靜態(tài)方法還是構(gòu)造函數(shù)。PowerMock 旨在通過少量方法和注釋擴(kuò)展現(xiàn)有的API,以啟用額外的功能。

          常用注解

          • @RunWith(PowerMockRunner.class) 告訴JUnit使用PowerMockRunner進(jìn)行測(cè)試。
          • @PrepareForTest({DemoDao.class}) 所有需要測(cè)試的類列在此處,適用于模擬final類或有final, private, static, native方法的類。
          • @PowerMockIgnore({"javax.management.", "javax.net.ssl."}) 為了解決使用powermock后,提示classloader錯(cuò)誤。
          • @SuppressStaticInitializationFor 不讓靜態(tài)代碼加載 其他更多注解可以參考:https://github.com/powermock/powermock/wiki/Suppress-Unwanted-Behavior。

          如何開始

          JUnit 4.4及以上
          <properties>
              <powermock.version>2.0.2</powermock.version>
          </properties>
          <dependencies>
             <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-module-junit4</artifactId>
                <version>${powermock.version}</version>
                <scope>test</scope>
             </dependency>
             <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-api-mockito2</artifactId>
                <version>${powermock.version}</version>
                <scope>test</scope>
             </dependency>
          </dependencies>

          powerMock樣例

          這是一個(gè)需要被mock的類,里面有私有方法、靜態(tài)方法等等下面就用這個(gè)類來演示各個(gè)方法的mock功能。

          /**
           *
           * @Date: 2020/3/31
           * @Description:
           */

          @Repository
          public class DemoDao {
              public String mockPublicMethod(String type) throws Throwable {
                  throw  new Throwable();
              }
              public final String mockFinalMethod(String type) throws Throwable {
                  throw  new Throwable();
              }
              public static String mockStaticMethod(String type) throws Throwable {
                  throw  new Throwable();
              }
          }
          /**
           * @Date: 2020/3/31 
           * @Description:
           */

          @Component
          public class DemoService extends AbstractDemo{

              @Autowired
              private DemoDao demoDao;

              public String mockPublicMethod() throws Throwable {
                  return demoDao.mockPublicMethod("demo");
              }

              public String mockFinalMethod() throws Throwable {
                  return demoDao.mockFinalMethod("demo");
              }

              public String mockStaticMethod() throws Throwable {
                  return DemoDao.mockStaticMethod("demo");
              }


              private String callPrivateMethod(String type) {
                  return type;
              }

              public String mockPublicMethodCallPrivateMethod(String type) throws Throwable {
                  return callPrivateMethodThrowable(type);
              }

              private String callPrivateMethodThrowable(String type) throws Throwable {
                  throw new Throwable();
              }

              public String mockExtendMethod(String type) throws Throwable {
                 return getExtendMethod();
              }

              public static String UUID = "uuid";
          }

          mock普通公共方法
             /**
              * @Date: 2020/4/24 
              * @Description:
              */

             @RunWith(PowerMockRunner.class)
             public class DemoServiceTest {
             
                 @InjectMocks
                 private DemoService demoService;
                 @Mock
                 private DemoDao demoDao;
                 
              /**
              * mock 普通方法
              * @throws Throwable
              */

                 @Test
                 public void mockPublicMethod() throws Throwable {
                     String type = UUID.randomUUID().toString();
                     PowerMockito.when(demoDao.mockPublicMethod(any())).thenReturn(type);
                     String result = demoService.mockPublicMethod();
                     Assert.assertEquals(type, result);
                 }
          mock Final方法

          跟普通方法是一樣的,唯一的區(qū)別是需要在類上加PrepareForTest注解

              @RunWith(PowerMockRunner.class)
              @PrepareForTest(DemoDao.class)
              public class DemoServiceTest {
              
                  @InjectMocks
                  private DemoService demoService;
                  @Mock
                  private DemoDao demoDao;
              
                 
                /**
                    * mock final方法
                    * @throws Throwable
                    */

                   @Test
                   public void mockFinalMethod() throws Throwable {
                       String type = UUID.randomUUID().toString();
                       PowerMockito.when(demoDao.mockFinalMethod(any())).thenReturn(type);
                       String result = demoService.mockFinalMethod();
                       Assert.assertEquals(type, result);
                   }
            
          mock靜態(tài)方法(使用 PowerMockito.mockStatic)被mock的類也要用PrepareForTest注解修飾。
            @RunWith(PowerMockRunner.class)
            @PrepareForTest(DemoDao.class)
            public class DemoServiceTest {
            
                @InjectMocks
                private DemoService demoService;
                @Mock
                private DemoDao demoDao;
                /**
                 * mock 靜態(tài)方法
                 * @throws Throwable
                 */

                @Test
                public void mockStaticMethod() throws Throwable {
                    String type = UUID.randomUUID().toString();
                    PowerMockito.mockStatic(DemoDao.class);
                    PowerMockito.when(DemoDao.mockStaticMethod(any())).thenReturn(type);
                    String result = demoService.mockStaticMethod();
                    Assert.assertEquals(type, result);
                }
          調(diào)用 private方法
              /**
               * 調(diào)用私有方法
               * 
               * @throws Throwable
               */

               /**
                  * 調(diào)用私有方法
                  * 
                  * @throws Throwable
                  */

                 @Test
                 public void callPrivateMethod() throws Throwable {
                     // 第一種方式
                     String type = UUID.randomUUID().toString();
                     Method method = PowerMockito.method(DemoService.class, "callPrivateMethod", String.class);
                     String result = (String) method.invoke(demoService, type);
                     Assert.assertEquals(type, result);
             
                     //第二種方式
                     String result1 = Whitebox.invokeMethod(demoService, "callPrivateMethod", type);
                     Assert.assertEquals(type, result1);
                 }
          mock 私有方法(被mock的類也要用PrepareForTest注解修飾。)
              /**
               * mock私有方法
               *
               * @throws Throwable
               */

              @Test
              public void mockPrivateMethod() throws Throwable {
                  String type = UUID.randomUUID().toString();
                  // 重點(diǎn)這一句
                  demoService = PowerMockito.spy(demoService);
                  PowerMockito.doReturn(type).when(demoService,"callPrivateMethodThrowable",type);
                  String result = demoService.mockPublicMethodCallPrivateMethod(type);
                  Assert.assertEquals(type, result);
              }
          mock父類方法
               /**
                 * mock父類方法
                 *
                 * @throws Throwable
                 */

                @Test
                public void mockExtendMethod() throws Throwable {
                    String type = UUID.randomUUID().toString();
                    // 需要mock的父類的方法
                    Method method = PowerMockito.method(AbstractDemo.class, "getExtendMethod");
                    // InvocationHandler
                    PowerMockito.replace(method).with((proxy, method1, args) -> type);
                    String result = demoService.mockExtendMethod(type);
                    Assert.assertEquals(type, result);
                }
          mock構(gòu)造方法
               public DemoService() {
                      throw new NullPointerException();
                  }
              @Test
              public void mockConstructorMethod() throws Throwable {
                  PowerMockito.whenNew(DemoService.class).withNoArguments().thenReturn(demoService);
              }
          mock字段
                  /**
                   * mock 字段
                   */

                  @Test
                  public void mockFiled(){
                      String uuid = UUID.randomUUID().toString();
                      Whitebox.setInternalState(DemoService.class, "UUID",uuid);
                      Assert.assertEquals(DemoService.UUID, uuid);
                  }

          結(jié)束

          • 由于自己才疏學(xué)淺,難免會(huì)有紕漏,假如你發(fā)現(xiàn)了錯(cuò)誤的地方,還望留言給我指出來,我會(huì)對(duì)其加以修正。
          • 如果你覺得文章還不錯(cuò),你的轉(zhuǎn)發(fā)、分享、贊賞、點(diǎn)贊、留言就是對(duì)我最大的鼓勵(lì)。
          • 感謝您的閱讀,十分歡迎并感謝您的關(guān)注。

          -End-

          最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

          點(diǎn)擊??卡片,關(guān)注后回復(fù)【面試題】即可獲取

          在看點(diǎn)這里好文分享給更多人↓↓

          瀏覽 31
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产999高清无码精品导航 | 青青草亚洲视频 | 91av免费 | 成人做爰黄AA片免费看三区 | 伊人综合电影网 |