我正在使用JUnit5测试Spring Boot应用程序。我想测试一个@Service
使用@Autowired
字段的对象。我想模拟@Service
测试对象间接使用的另一个对象。具体而言,我具有以下(高度简化的)设置:
被测试的对象:
@Service
public class MainService {
private @Autowired SubService subService;
public String test() {
return subService.test();
}
}
SubService
:
@Service
public class SubService {
private @Autowired StringService stringService;
public String test() {
return stringService.test();
}
}
StringService
:
@Service
public class StringService {
public String test() {
return "Real service";
}
}
使用的测试类:
@SpringBootTest
public class MainServiceTest {
private @Autowired MainService mainService;
private @MockBean StringService stringService;
@BeforeEach
public void mock() {
Mockito.when(stringService.test()).thenReturn("Mocked service");
}
@Test
public void test() {
assertEquals("Mocked service", mainService.test());
}
}
如果我将测试类作为来运行,则上述方法有效@SpringBootTest
,但这会加载整个应用程序,并且运行速度很慢。我也想避免,@WebMvcTest
因为我不需要Web服务器,或者@DataJpaTest
因为我不需要持久性。我不想嘲笑SubService
,因为它包含我想和一起测试的功能MainService
。
我尝试了以下方法:
@ExtendWith(SpringExtension.class)
=> throws NoSuchBeanDefinitionException
,在这种情况下自动布线似乎不起作用@ExtendWith(MockitoExtension.class)
并使用@InjectMocks
和@Mock
而不是Spring批注=>,因为这StringService
不是MainService
被测试的直接字段,所以不起作用。有没有一种方法可以使用spring依赖注入系统而不加载Web服务器或持久层,或者不使用Spring测试而是允许“嵌套”依赖注入?
您可以使用概要分析(即Spring @Profile
)来避免加载整个应用程序。它将类似于以下内容:
@Profile("test")
@Configuration
public class TestConfiguration {
@Bean
public MainService mainService() {
return new MainService();
}
@Bean
public SubService subService() {
return new SubService();
}
// mock the StringService
@Bean
public StringService stringService() {
return Mockito.mock(StringService.class);
}
}
然后将该配置文件与`@SpringBootTest(classes = TestConfiguration.class)一起使用,它将类似于以下内容:
@ActiveProfiles("test")
@SpringBootTest(classes = TestConfiguration.class)
class MainServiceTest {
@Autowired
private MainService mainService;
@Test
public void test() {
// configure behavior using apis like when(), basically however you
// want your mock to behave
}
}
这将仅加载类中定义的bean TestConfiguration
。注意:由于您的问题更多是关于如何避免加载整个应用程序的问题,因此我已经集中回答了。上面的方法可以完成工作,但是在任何给定的一天,我都希望构造函数连接比其他任何形式的依赖注入更容易维护和测试(例如您要模拟的情况)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句