我开始写一个围绕硬件特定功能的机器人电子测试,比如传感器和摄像头(正面和背面)。
想象一下这个类:
class CheckHardware {
private bolean hasCamera(Context context) {
PackageManager pm = context.callingActivityContext
.getPackageManager();
// camera support
Boolean frontCam = pm.hasSystemFeature("android.hardware.camera.front");
Boolean rearCam = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
if (frontCam || rearCam) {
return true;
}
return false;
}
}所以我想测试不同的场景,有前置摄像头和后置摄像头,只有前置摄像头或根本没有摄像头。在我的应用程序中,它有点复杂,但希望这能让它更容易理解我的意思。
现在我是这样做的,感觉有点奇怪。
RobolectricPackageManager pm = (RobolectricPackageManager) Robolectric.application.getPackageManager();
pm.setSystemFeature(PackageManager.FEATURE_CAMERA, true);我考虑过编写自己的测试运行器,所以对于所有预期的硬件设置,都需要一个像这样的特定运行器
public class WithCameraTestRunner extends RobolectricTestRunner {
@Override
public void setupApplicationstate(RobolectricConfig robolectricConfig) {
super.setupApplicationState(robolectricConfig);
ShadowApplication shadowApplication = shadowOf(Robolectric.application);
shadowApplication.setPackageName(robolectricConfig.getPackageName());
RobolectricPackageManager pm = new RobolectricPackageManager(Robolectric.application, robolectricConfig)
pm.setSystemFeature(PackageManager.FEATURE_CAMERA, true);
shadowApplication.setPackageManager(pm);
}
}我对此也不太满意,因为我想在同一个测试中测试不同的场景。
有什么想法吗?解决这个问题的最好方法是什么?
发布于 2013-02-15 13:49:49
这可以使用JUnit规则来完成。我在使用JUnit 4.8.2时编写了这个示例。
下面是测试类:
public class CameraTest {
@Rule
public CameraRule rule = new CameraRule();
@Test
@EnableCamera
public void testWithCamera() {
Assert.assertTrue(CameraHolder.CAMERA);
}
@Test
public void testWithoutCamera() {
Assert.assertFalse(CameraHolder.CAMERA);
}
}规则是这样的:
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
public class CameraRule implements MethodRule {
@Override
public Statement apply(Statement base, FrameworkMethod method, Object target) {
boolean camera = false;
if (method.getAnnotation(EnableCamera.class) != null) {
camera = true;
}
return new CameraStatement(camera, base);
}
}我包含了导入,这样您就可以看到它们的来源。语句是一个只有一个函数evaluate()的接口。
下面是statement类:
import org.junit.runners.model.Statement;
public class CameraStatement extends Statement {
private boolean mEnabled;
private Statement mStatement;
public CameraStatement(boolean enabled, Statement statement) {
mEnabled = enabled;
mStatement = statement;
}
@Override
public void evaluate() throws Throwable {
CameraHolder.CAMERA = mEnabled;
mStatement.evaluate();
}
}除了启用的boolean之外,您还可以轻松地传入一个枚举或您想要启用的特性的枚举的Set。确保禁用所有未明确启用的功能。在本例中,如果您没有显式地将enabled设置为true,那么它将为false。
以下是注释本身的代码:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableCamera {
}这样,除了使用@Test之外,还可以使用@EnableCamera对该函数进行注释。
public class CameraHolder {
public static boolean CAMERA = false;
}RobolectricPackageManager pm = (RobolectricPackageManager) Robolectric.application.getPackageManager();
// My version of robolectric didn't have this function.
pm.setSystemFeature(PackageManager.FEATURE_CAMERA, true);https://stackoverflow.com/questions/14741785
复制相似问题