qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          基于spring與mockito單元測試Mock對象注入

          1.關鍵詞
            單元測試、spring、mockito
            2.概述
            單元測試目前已經成為項目中保證代碼質量的一種必要方法,對于一些不易構造或者不易獲取的對象通過mock的方式進行測試是一種很有效的處理辦法。在基于spring的mock測試中,mock對象獲取和使用的便利性可以提升單元測試代碼的質量。
            3.實現原理
            Mock對象的注入使用注解和反射,對象注入依賴spring框架支持junit4提供的TestExcutionListeners監聽器對象,在監聽器中將mock對象注入到單元測試類中。
            4.新建對象方式代碼
          private IAccessServiceaccessService = Mockito.mock(IAccessService.class);
          @BeforeClass
          public static void beforeClass(){
          // 構造并注入Mock對象ICmsProxyService
          sceneConfigService.setAccessService(accessService);
          }
            5.監聽器方式代碼
            5.1  實現監聽器
            繼承DependencyInjectionTestExecutionListener類,
            實現injectDependencies(TestContexttestContext)方法
          public class MockitoDependencyInjectionTestExecutionListener extends
          DependencyInjectionTestExecutionListener {
          @Override
          protected void injectDependencies(TestContext testContext) throws Exception {
          super.injectDependencies(testContext);
          init(testContext);
          }
            5.2 利用反射注入mock對象
          private void init(final TestContext testContext)throws Exception {
          Object bean = testContext.getTestInstance();
          Field[] fields = bean.getClass().getDeclaredFields();
          for (Field field : fields) {
          Annotation[] annotations = field.getAnnotations();
          for (Annotation annotation : annotations) {
          if(annotationinstanceof Mock){
          //注入Mock實例
          MockObject obj = new MockObject();
          obj.setType(field.getType());
          obj.setObj(Mockito.mock(field.getType()));
          field.setAccessible(true);
          field.set(bean, obj.getObj());
          mockObjectMap.put(field.getName(), obj);
          }else if(annotation instanceofAutowired){
          injectFields.add(field);
          }
          }
          }


          AutowireCapableBeanFactory factory =testContext.getApplicationContext().getAutowireCapableBeanFactory();
          //Autowired注解注入mock對象
          for (Field field :injectFields) {
          field.setAccessible(true);
          Object object = field.get(bean);
          if(objectinstanceof Proxy){
          Class targetClass = AopUtils.getTargetClass(object);
          if(targetClass ==null)
          return;
          Field[] targetFields =targetClass.getDeclaredFields();
          for(Field targetField : targetFields){
          targetField.setAccessible(true);
          if(mockObjectMap.get(targetField.getName()) ==null){
          continue;
          }
          targetField.set(getTargetObject(object,mockObjectMap.get(targetField.getName()).getType()),mockObjectMap.get(targetField.getName()).getObj());
          }
          }else{
          Object realObject = factory.getBean(field.getName());
          if(null != realObject){
          Method[] methods = realObject.getClass().getDeclaredMethods();
          for (Method method : methods) {
          if(method.getName().equalsIgnoreCase("set" +field.getName())){
          method.invoke(realObject, mockObjectMap.get(field.getName()).getObj());
          }
          }
          }
          }
          }
          }
            5.3 測試類配置
            使用@TestExecutionListeners注解,引入監聽器,需要mock的對象加上@Mock注解。
          @TestExecutionListeners({MockitoDependencyInjectionTestExecutionListener.class})
          public class AccessServiceImplTest extends BaseTestCase{
          @Autowired
          private IAccessServiceaccessService;
          @Mock
          private IPersonServicepersonService;
          @Mock
          private IAccessDaoaccessDao;
          }
            6.總結
            監聽器的方式解放了代碼中硬編碼注入mock對象,使得代碼簡潔干凈。

          posted on 2014-03-07 10:39 順其自然EVO 閱讀(4992) 評論(0)  編輯  收藏 所屬分類: 測試學習專欄

          <2014年3月>
          2324252627281
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 什邡市| 太和县| 钟祥市| 屏山县| 霸州市| 三江| 香港 | 铜鼓县| 广灵县| 资兴市| 方山县| 长沙县| 施秉县| 克山县| 合肥市| 梓潼县| 汶川县| 宜良县| 雷山县| 清新县| 望都县| 报价| 营山县| 开封县| 扶余县| 江华| 白河县| 泌阳县| 四平市| 军事| 进贤县| 南昌县| 潼南县| 牡丹江市| 南皮县| 宁陵县| 仁布县| 福鼎市| 囊谦县| 榆社县| 泌阳县|