如何测试Sample类的doSomething方法?避免调用抽象类A的process方法
测试Sample类doSomething方法时跳过抽象类A的process方法的解决方案
要实现不调用抽象类A的process方法,核心是让Sample的serviceMap中存入Mock的A实例,并对该实例的process方法设置空操作。以下是两种可行的实现方式:
方式一:基于Spring上下文的测试(@SpringBootTest)
这种方式适合依赖Spring环境的场景,利用@MockBean自动替换上下文里的A类型Bean,自动触发@PostConstruct初始化serviceMap:
@SpringBootTest public class SampleTest { @Autowired private Sample sample; // 生成Mock的A实例,自动注入到Sample的services列表中 @MockBean private A targetMockService; @BeforeEach void setUp() { // 指定Mock实例的getName返回目标serviceName,确保能被serviceMap正确映射 when(targetMockService.getName()).thenReturn("your-target-service-name"); // 设置process方法执行空操作,跳过真实逻辑 doNothing().when(targetMockService).process(any()); } @Test void testDoSomething() { // 执行待测试方法 sample.doSomething(); // 可选:验证process方法是否按预期被调用 verify(targetMockService, times(1)).process(any()); } }
方式二:纯Mockito轻量测试
如果不需要Spring上下文,可直接用Mockito注解配合反射完成测试,更高效:
@ExtendWith(MockitoExtension.class) public class SampleTest { // 待测试的Sample实例,Mockito会自动注入依赖 @InjectMocks private Sample sample; // Mock的A实例 @Mock private A targetMockService; @BeforeEach void setUp() { // 手动构建services列表并注入到Sample的私有字段中 List<A> mockServices = Collections.singletonList(targetMockService); ReflectionTestUtils.setField(sample, "services", mockServices); // 手动调用init方法初始化serviceMap(无Spring时不会自动触发@PostConstruct) sample.init(); // 设置Mock实例的行为 when(targetMockService.getName()).thenReturn("your-target-service-name"); doNothing().when(targetMockService).process(any()); } @Test void testDoSomething() { sample.doSomething(); verify(targetMockService).process(any()); } }
关键说明
- 无论哪种方式,都要保证
serviceMap中存储的是Mock的A实例,这样调用process时才会触发我们设置的空操作 - 如果有多个不同名称的A实现需要Mock,只需添加多个
@MockBean(或@Mock)实例,并分别指定getName的返回值即可
内容的提问来源于stack exchange,提问作者Rohit Raj
相关产品推荐
相关产品推荐

