如何使用Mockito为Android setOrientation方法编写JUnit单元测试
待测试方法的Mockito单测实现方案
前置准备
- 测试目标:持有
setOrientation方法的业务工具类,测试过程不依赖真实Android运行环境 - Mock范围:方法内部所有涉及系统资源、硬件状态的调用(包括Activity、DisplayMetrics、Configuration、Resources等Android系统类)
- 注解依赖:使用Mockito原生注解完成依赖注入,包括
@Mock标记模拟对象、@InjectMocks标记真实测试对象
测试用例拆分逻辑
原方法的核心触发逻辑为两个条件同时满足才执行屏幕方向设置,因此需要覆盖所有分支组合:
- 对角线尺寸≥6.5英寸 + 硬键盘已连接:验证屏幕方向设置动作被正确触发
- 对角线尺寸<6.5英寸 + 硬键盘已连接:验证屏幕方向设置动作未触发
- 对角线尺寸≥6.5英寸 + 硬键盘未连接:验证屏幕方向设置动作未触发
- 边界值校验:对角线恰好等于6.5英寸时,验证分支判断的准确性
具体测试代码示例
原
setOrientation方法内部实际依赖的Android系统调用:
- 通过
Activity.getResources()获取设备的DisplayMetrics参数(像素密度、宽高像素),计算屏幕对角线尺寸- 通过
Resources.getConfiguration()读取键盘状态,判断硬键盘是否连接- 调用
Activity.setRequestedOrientation()完成屏幕方向设置
@RunWith(MockitoJUnitRunner.class) public class OrientationAdjusterTest { @InjectMocks private OrientationAdjuster adjuster; // 持有setOrientation方法的真实业务类 @Mock private Activity mockActivity; @Mock private Resources mockResources; @Mock private DisplayMetrics mockDisplayMetrics; @Mock private Configuration mockConfiguration; // 测试触发场景:大屏+硬键盘 @Test public void setOrientation_whenLargeScreenWithHardKeyBoard_setOrientationSuccess() { // 构造6.8英寸大屏的DisplayMetrics返回值 when(mockActivity.getResources()).thenReturn(mockResources); when(mockResources.getDisplayMetrics()).thenReturn(mockDisplayMetrics); mockDisplayMetrics.densityDpi = 420; mockDisplayMetrics.widthPixels = 1080; mockDisplayMetrics.heightPixels = 2400; // 构造硬键盘已连接的Configuration返回值 when(mockResources.getConfiguration()).thenReturn(mockConfiguration); mockConfiguration.keyboard = Configuration.KEYBOARD_QWERTY; mockConfiguration.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO; // 执行待测方法 adjuster.setOrientation(mockActivity); // 验证:正确调用了屏幕方向设置方法 verify(mockActivity).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } // 测试非触发场景:小屏+硬键盘 @Test public void setOrientation_whenSmallScreenWithHardKeyBoard_notSetOrientation() { // 构造5.8英寸小屏的DisplayMetrics返回值 when(mockActivity.getResources()).thenReturn(mockResources); when(mockResources.getDisplayMetrics()).thenReturn(mockDisplayMetrics); mockDisplayMetrics.densityDpi = 440; mockDisplayMetrics.widthPixels = 1080; mockDisplayMetrics.heightPixels = 2340; when(mockResources.getConfiguration()).thenReturn(mockConfiguration); mockConfiguration.keyboard = Configuration.KEYBOARD_QWERTY; mockConfiguration.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO; adjuster.setOrientation(mockActivity); // 验证:未调用任何屏幕方向设置方法 verify(mockActivity, never()).setRequestedOrientation(anyInt()); } // 测试非触发场景:大屏+软键盘 @Test public void setOrientation_whenLargeScreenWithSoftKeyBoard_notSetOrientation() { // 构造6.8英寸大屏的DisplayMetrics返回值 when(mockActivity.getResources()).thenReturn(mockResources); when(mockResources.getDisplayMetrics()).thenReturn(mockDisplayMetrics); mockDisplayMetrics.densityDpi = 420; mockDisplayMetrics.widthPixels = 1080; mockDisplayMetrics.heightPixels = 2400; // 构造硬键盘未连接的Configuration返回值 when(mockResources.getConfiguration()).thenReturn(mockConfiguration); mockConfiguration.keyboard = Configuration.KEYBOARD_QWERTY; mockConfiguration.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES; adjuster.setOrientation(mockActivity); verify(mockActivity, never()).setRequestedOrientation(anyInt()); } }
编写注意事项
- 所有Android系统类的返回值全部通过Mockito自定义构造,禁止调用真实系统逻辑,保证测试执行速度和环境稳定性
- 对6.5英寸的边界值做单独测试,验证计算逻辑和分支判断的精度
- 验证方法调用时优先使用精确匹配,比如校验
setRequestedOrientation传入的具体方向值,避免传入错误参数的逻辑漏洞被忽略 - 屏幕尺寸计算逻辑建议抽离为独立的纯函数,单独编写测试覆盖不同尺寸计算场景,降低
setOrientation方法本身的测试复杂度
内容的提问来源于stack exchange,提问作者nikitha gullapalli
相关产品推荐
相关产品推荐

