云自無心水自閑

          天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
          本文將簡單介紹如何使用PowerMock和Mockito來mock
          1. 構造函數
          2. 靜態函數
          3. 枚舉實現的單例
          4. 選擇參數值做為函數的返回值
          5. 在調用mock出來的方法中,改變方法參數的值

          一點簡要說明:Mockito其實已經可以滿足大部分的需求,但是它的實現機制是使用cglib來動態創建接口的類的實例。但是這種實現方式不能用于構造函數和靜態函數,因為那需要使用類的字節碼(比如使用javassist). 所以我們才需要結合使用PowerMock.

          1. mock構造函數, 如果有代碼沒有使用DI注入依賴實例,在單元測試中可以使用PowerMock來模擬創建對象。
          注意的開始兩行的2個注解 @RunWith 和 @PrepareForTest
          @RunWith比較簡單,后面始終是PowerMockRunner.class
          @PrepareForText后面需要加的是調用構造函數的類名,而不是有構造函數的類本身。
          在下面的例子中,我們要測試的類是:Helper, 在Helper類中調用了Somthing類的構造函數來創建實例。
          @RunWith(PowerMockRunner.class)
          @PrepareForTest(Helper.
          class)
          public class HelperTest {
            @Mock
            
          private Something mockSomething;
                
            @InjectMocks
            
          private Helper helper;
                
            @Test
            
          public void doSomething() throws Exception {
                String argument 
          = "arg";
                    
                PowerMockito.whenNew(Something.
          class).withArguments(argument).thenReturn(mockSomething);
                   
                // 調用需要測試方法
                helper.doSomething(argument);
                   
                // 進行驗證
                verify(mockSomething).doIt();
            }
          }


          public class Helper {
            public void doSomething(String arg) {
                Something something = new Something(arg);
                something.doit();
            }
          }


          2,mock 靜態函數, 單例模式就是一個典型的會調用靜態函數的例子。 注意要點與mock構造函數相同。
          class ClassWithStatics {
            
          public static String getString() {
              
          return "String";
            }

            
          public static int getInt() {
              
          return 1;
            }
          }

          @RunWith(PowerMockRunner.
          class)
          @PrepareForTest(ClassWithStatics.
          class)
          public class StubJustOneStatic {
            @Test
            
          public void test() {
              PowerMockito.mockStatic(ClassWithStatics.
          class);

              when(ClassWithStatics.getString()).thenReturn(
          "Hello!");

              System.out.println(
          "String: " + ClassWithStatics.getString());
              System.out.println(
          "Int: " + ClassWithStatics.getInt());
            }
          }

          3。mock枚舉實現的單例
          SingletonObject.java
          public enum SingletonObject { 
              INSTANCE
          ;
              private
          int num;
              protected
          void setNum(int num) {
                  this.num = num;
              }
              public int getNum() {
                  return
          num;
              }

          }
          SingletonConsumer.java

          public class SingletonConsumer {
              public String consumeSingletonObject() { 
                  return
          String.valueOf(SingletonObject.INSTANCE.getNum());
              }
          }
          SingletonConsumerTest.java
          @RunWith(PowerMockRunner.class) 
          @PrepareForTest({SingletonObject.class})
          public class SingletonConsumerTest {
              @Test public void testConsumeSingletonObject() throws Exception {
                  SingletonObject
          mockInstance = mock(SingletonObject.class);
                  Whitebox
          .setInternalState(SingletonObject.class, "INSTANCE", mockInstance);
                  when
          (mockInstance.getNum()).thenReturn(42);
                  assertEquals
          ("42", new SingletonConsumer().consumeSingletonObject());
              }
          }
          4。返回參數值做為函數返回值。
          mockito 1.9.5之后,提供一個方便的方法來實現這個需要,在這之前可以使用一個匿名函數來返回一個answer來實現。
          when(myMock.myFunction(anyString())).then(returnsFirstArg());
          其中returnsFirstArg()是org.mockito.AdditionalAnswers中的一個靜態方法。
          在這個類中還有其他的一些類似方法
          returnsSecondArg()
          returnsLastArg()
          ReturnsArgumentAt(int position)

          5. 在調用mock出來的方法中,改變方法參數的值
          when( myMock.someMethod( any( List.class ) ) ).thenAnswer( ( new Answer<Void>() {
              @Override
              
          public Void answer( InvocationOnMock invocation )
                      
          throws Throwable {
                  Object[] args 
          = invocation.getArguments();
                  List arg1 
          = (List)args[0];
                  arg1.add(
          "12345");
                  
          return null;
              }
          } ) );



          Verifying with generic parameters
          verify(someService).process(Matchers.<Collection<Person>>any());
          verify(adunoMasterBaseProcessor).processBinFiles( anyListOf(File.class) );


          主站蜘蛛池模板: 玉林市| 松溪县| 乌兰浩特市| 会东县| 平乡县| 昔阳县| 贵南县| 威远县| 柏乡县| 沂水县| 华宁县| 安康市| 扎囊县| 忻州市| 普洱| 芒康县| 岚皋县| 五华县| 永新县| 江西省| 太湖县| 德化县| 维西| 洪雅县| 阿鲁科尔沁旗| 河池市| 漳州市| 松阳县| 德令哈市| 绵阳市| 门头沟区| 黔西县| 玉屏| 镇平县| 康平县| 岱山县| 禹城市| 四会市| 宾阳县| 古蔺县| 麻江县|