如何使用Mockito测试setDeviceColor方法?我无法完成该测试
用Mockito实现
setDeviceColor的参数化测试 没问题,我来一步步教你覆盖这个方法的所有测试场景。先拆解下这个方法的核心逻辑:
- 当传入的
deviceColor为0时,会调用ColorUtil.getColorFromConte()获取颜色值,再赋值给mDeviceColor - 当传入非0值时,直接将传入值赋值给
mDeviceColor - 两种场景下最终都会调用
notifyPropertyChanged(BR.deviceColor)
接下来结合Mockito和JUnit参数化测试来完成测试:
1. 先准备测试依赖
如果用Maven,确保pom.xml包含这些依赖(Gradle可对应调整):
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-params</artifactId> <version>5.9.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
2. 测试类完整实现
假设这个方法属于DeviceViewModel类,测试代码如下:
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class DeviceViewModelTest { @Mock private Context mContext; // Mock上下文对象 // 用CsvSource批量提供测试用例:输入颜色值、预期最终颜色、是否需要调用ColorUtil @ParameterizedTest @CsvSource({ "0, 0xFF123456, true", // 假设ColorUtil返回0xFF123456 "123, 123, false", "-1, -1, false" }) void testSetDeviceColor(int inputColor, int expectedColor, boolean shouldCallColorUtil) { // 1. 实例化被测对象,注入mock的上下文 DeviceViewModel viewModel = new DeviceViewModel(mContext); // 2. Mock静态方法ColorUtil(Mockito 3.4+支持静态类Mock) try (MockedStatic<ColorUtil> mockedColorUtil = mockStatic(ColorUtil.class)) { if (shouldCallColorUtil) { // 指定静态方法的返回值 mockedColorUtil.when(() -> ColorUtil.getColorFromConte(mContext, R.color.color_1)) .thenReturn(expectedColor); } // 3. 调用被测方法 viewModel.setDeviceColor(inputColor); // 4. 验证逻辑正确性 if (shouldCallColorUtil) { // 验证静态方法被调用一次 mockedColorUtil.verify(() -> ColorUtil.getColorFromConte(mContext, R.color.color_1), times(1)); } else { // 验证静态方法从未被调用 mockedColorUtil.verify(() -> ColorUtil.getColorFromConte(any(Context.class), anyInt()), never()); } // 验证mDeviceColor被设置为预期值(建议给ViewModel加getDeviceColor()方法,或用反射获取私有变量) assertEquals(expectedColor, viewModel.getDeviceColor()); // 验证属性变更通知被触发 verify(viewModel, times(1)).notifyPropertyChanged(BR.deviceColor); } } }
关键细节说明
- 参数化测试:用
@CsvSource批量定义测试场景,一次运行就能覆盖0、正整数、负整数等多种情况 - 静态方法Mock:用
MockedStatic(try-with-resources语法)确保静态mock在测试后自动清理,避免影响其他测试 - 验证逻辑:
- 针对0值场景,确认静态方法被正确调用,返回值被赋值
- 针对非0值场景,确认静态方法未被调用,输入值直接生效
- 所有场景都验证
notifyPropertyChanged的调用,确保属性变更通知正常
额外注意点
- 如果用JUnit 4,参数化测试要改用
@RunWith(Parameterized.class),静态Mock可能需要PowerMock(Mockito 3.4之前版本不支持静态mock) - 若
mDeviceColor是私有变量,建议添加getDeviceColor()测试专用方法,或用反射工具类读取私有值 - 确保测试环境能正常访问
R.color.color_1,必要时可Mock资源ID的返回逻辑
内容的提问来源于stack exchange,提问作者rahul kumar abhishek
相关产品推荐
相关产品推荐

