我想检查我的应用程序在其运行的设备没有摄像头时是否显示错误消息。我尝试传入一个模拟上下文,但是当我尝试模拟 CameraManager 类时,mockito 给出了一个错误,因为它被声明为 final。 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());
}
}
最佳答案
不幸的是,您不能模拟 final
类。
几乎没有选项/技巧:
- 尝试添加Robolectric库并用它编写测试
ShadowCamera
- 将与
CameraManager
相关的逻辑移动到一个单独的类中,并将其注入(inject)到 Activity 中。然后在测试项目中,您可以覆盖此注入(inject)。 非常相似的想法 - 创建一个
接口(interface) OnCameraManagerInterface
public interface OnCameraManagerInterface { String[] getListOfCameras() throws CameraAccessException; }
然后在Activity中实现:
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]; } }
在 list 中:
<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()); } }
我很确定,即使不将 TestActivity 添加到主要源代码中并显示(将其保留在 androidTest 中,虽然我没有看),它也是可行的
不创建新 Activity 的混合变体:
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; } }
那么您的 Activity 将如下所示:
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();
希望对你有帮助
关于Android - 在测试我的应用程序时如何模拟缺少相机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34546409/