2015-12-31 41 views
1

我想檢查一下,當它運行的設備沒有攝像頭時,我的應用程序會顯示一條錯誤消息。我嘗試傳遞一個模擬上下文,但當我試圖模擬CameraManager類時,mockito給出了一個錯誤,因爲它聲明爲final。當然,android有一個簡單的解決方案呢?這是我的嘗試:Android - 測試我的應用程序時,如何模擬缺相機?

public class CreateNewIdentityActivityUnitTest extends ActivityUnitTestCase<CreateNewIdentityActivity> { 
    public CreateNewIdentityActivityUnitTest() { 
     super(CreateNewIdentityActivity.class); 
    } 

    public void testErrorMessageDisplayedWhenNoCamerasExist() throws Exception { 
     // Create the mock cameramanager 
     // THIS LINE FAILS BECAUSE CAMERAMANAGER IS FINAL 
     CameraManager mockCameraManager = mock(CameraManager.class); 
     String[] cameraIdList = {}; 
     when(mockCameraManager.getCameraIdList()).thenReturn(cameraIdList); 

     // Create the mock context 
     Context mockContext = mock(Context.class); 
     when(mockContext.getSystemService(Context.CAMERA_SERVICE)).thenReturn(mockCameraManager); 

     // Start the activity 
     Intent intent = new Intent(mockContext, CreateNewIdentityActivity.class); 
     Activity activity = startActivity(intent, null, null); 

     // Verify that the error message was made visible 
     TextView errorTextView = (TextView)activity.findViewById(R.id.ErrorTextView); 
     assertNotNull(errorTextView); 
     assertEquals(View.VISIBLE, errorTextView.getVisibility()); 
    } 
} 

回答

1

不幸的是,你不能嘲笑final類。

有是幾個選項/黑客:

  • 嘗試添加Robolectric庫,並編寫測試與它的相關CameraManager成一個單獨的類ShadowCamera
  • 移動邏輯和活動注入它。然後在Test項目中,您可以重寫此注入。
  • 漂亮類似的想法 - 建立一個interface OnCameraManagerInterface

    public interface OnCameraManagerInterface { 
        String[] getListOfCameras() throws CameraAccessException; 
    } 
    

    然後在活動實現:

    public class CreateNewIdentityActivity extends AppCompatActivity 
         implements OnCameraManagerInterface { 
        ....... 
        @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
        @Override 
        public String[] getListOfCameras() throws CameraAccessException { 
         return ((CameraManager)getSystemService(Context.CAMERA_SERVICE)). 
            getCameraIdList(); 
        } 
    } 
    

    並在代碼,在那裏你檢查相機的存在 - 撥打:if (getListOfCameras().length == 0) {}

    現在,添加新的TestCreateNewIdentityActivity以覆蓋您的CreateNewIdentityActivity

    public class TestCreateNewIdentityActivity extends CreateNewIdentityActivity { 
        @Override 
        public String[] getListOfCameras() throws CameraAccessException { 
         return new String[0]; 
        } 
    } 
    

    在清單:

    <activity android:name=".TestCreateNewIdentityActivity" 
         android:theme="@style/AppTheme.NoActionBar"/> 
    

    和測試看起來像:

    public class CreateNewIdentityActivityUnitTest extends ActivityUnitTestCase<TestCreateNewIdentityActivity> { 
        public CreateNewIdentityActivityUnitTest() { 
         super(TestCreateNewIdentityActivity.class); 
        } 
    
        public void testErrorMessageDisplayedWhenNoCamerasExist() throws Exception { 
         // Verify that the error message was made visible 
         TextView errorTextView = (TextView)getActivity().findViewById(R.id.ErrorTextView); 
         assertNotNull(errorTextView); 
         assertEquals(View.VISIBLE, errorTextView.getVisibility()); 
        } 
    } 
    

    我敢肯定,它甚至是可行的不添加測試活動進入主源代碼和體現(以保持它在androidTest,雖然我沒看)

  • 混合變種沒有創建新的活動:

    public class ActivityCameraManager { 
    
        private boolean isTest = false; 
        private CameraManager cameraManager; 
    
        public ActivityCameraManager(CameraManager cameraManager) { 
         this.cameraManager = cameraManager; 
        } 
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
        public String[] getListOfCameras() throws CameraAccessException { 
         if (isTest) { 
          return new String[0]; 
         } 
    
         return cameraManager.getCameraIdList(); 
        } 
    
        public void setTestMode() { 
         isTest = true; 
        } 
    } 
    

    那麼你的活動是要去樣子:

    public class MainActivity extends AppCompatActivity { 
    
        ActivityCameraManager activityCameraManager; 
    
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         ... 
         activityCameraManager = new ActivityCameraManager((CameraManager) getSystemService(Context.CAMERA_SERVICE)); 
        } 
    
        public void setActivityCameraManagerForTest() { 
         activityCameraManager.setTestMode(); 
        } 
    } 
    

    而且在測試只需撥打getActivity().setActivityCameraManagerForTest();

我希望,它有助於

1

答案是晚,但這裏Android的模擬相機示例。

你可以從視頻文件

textureVideoInputSource = new VideoFileInputSource(this, "mock_input_video.mp4"); 

設置VideoFileInputSource到模擬攝像機或您可以爲視頻流硬件攝像頭。

textureVideoInputSource = new CameraTextureVideoInputSource(this); 

你可以參考這裏的答案。 https://stackoverflow.com/a/38456189/1053097

+0

這是否適用於靜態圖片?我嘗試了一個PNG文件,但它不起作用。 –

+0

您可以將位圖轉換爲紋理並加載到GLSurfaceView。 – muneikh

+0

謝謝。我應該得到紋理,加載它在CameraActivity.java,我改變this.videoRenderer =新的VideoRenderer(CameraActivity.this,this.textureVideoInputSource); to this.videoRenderer = new VideoRenderer(CameraActivity.this,this.texture);假設我有一個名爲text的私人類成員。我知道這似乎並不正確。 –

相關問題