如何解决在Spring Boot中没有Web或持久层时,是否可以测试嵌套对象?
我正在使用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)
=>抛出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
}
}
这将仅加载类TestConfiguration
中定义的bean。
注意:由于您的问题更多是关于如何避免加载整个应用程序的问题,因此我已经专注于此。上面的方法可以完成工作,但是我更喜欢在任何给定的一天构造函数连接而不是依赖注入的任何其他方式,它更易于维护和测试(例如您要模拟的情况)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。