sat*_*the 5 java spring unit-testing mocking spring-boot
我正在使用 spring boot 开发一个rest api。它由标准层组成:控制器(@RestController)(处理传入的http请求并公开api端点),然后是服务层(@Service),最后是存储库层(@Repository)
我的问题是关于单元测试的。
为了测试我的控制器 - 我使用mockito模拟对服务层的调用。另外,为了防止不必要地加载整个上下文,我阅读了一些有关“弹簧片”的内容,因此为了测试我的控制器 - 这是使用的注释:
@WebMvcTest
@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = TieredClaimController.class)
class TieredClaimControllerTest {
@MockBean
private TieredClaimService tieredClaimService;
@Autowired
private MockMvc mockMvc;
Run Code Online (Sandbox Code Playgroud)
类似地,为了测试我的 Spring 数据存储库,使用了另一个 Spring 切片注释:@DataJpaTest
@ExtendWith(SpringExtension.class)
@DataJpaTest
@ContextConfiguration(initializers = {SalesRepositoryTest.Initializer.class})
public class SalesRepositoryTest {
@Autowired
private SalesRepository repository;
Run Code Online (Sandbox Code Playgroud)
因此,我可以看到针对 Web 端(@WebMvcTest)和数据库端(@DataJpaTest)的专用 spring 切片注释
但是,当我需要测试我的 @Service 注解的类时,我应该使用哪个 spring 切片?我没有看到任何专门用于服务层的内容
我问的原因是我以这种方式使用它:注意(对存储库的调用是模拟的,所以本质上我的服务层单元测试是隔离的)
@ExtendWith(SpringExtension.class)
@SpringBootTest
class TieredClaimServiceTest {
@Autowired
private TieredClaimService tieredClaimService;
@MockBean
private SalesRepository salesRepository;
Run Code Online (Sandbox Code Playgroud)
然而问题是 - 当我运行这些单元测试时,会调用一些不必要的 jpa/hibernate 代码。
我该如何防止这种情况?
2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook 调试| org.hibernate.SQL | 删除表discount_tiers(如果存在) Hibernate:删除表discount_tiers(如果存在) 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook 调试| org.hibernate.SQL | 如果存在则删除表商品 Hibernate:如果存在则删除表商品 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook 调试| org.hibernate.SQL | 删除表销售(如果存在) Hibernate:删除表销售(如果存在) 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook 调试| org.hibernate.SQL | 删除表用户(如果存在) Hibernate:删除表用户(如果存在) 2019-11-29 | 21:04:17.309 | SpringContextShutdownHook | SpringContextShutdownHook 调试| org.hibernate.SQL | 如果存在 hibernate_sequence 则删除序列 Hibernate:如果存在 hibernate_sequence* 则删除序列
2019-11-29 | 21:04:17.309 | SpringContextShutdownHook | SpringContextShutdownHook 调试| ohtsTypeConfiguration$范围 | 从 SessionFactory [org.hibernate.internal.SessionFactoryImpl@17fddecd] 取消 TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@89296ce] 的作用域
我想这些会出现在日志中,因为在我的 application.properties (在 /src/test/resources 下)我有这个:
spring.jpa.hibernate.ddl-auto=create-drop
但是,当我对存储库层进行单元测试时,我需要此配置,因此我无法删除或删除它
那么对于我的服务层有没有 spring 切片注释?当我测试与数据库/存储库隔离的服务层(因为该层被模拟)时,如何避免发生 hibernate/jpa 调用或加载?
编辑1: 根据下面的答案,我想我没有提供服务类的完整详细信息:我尝试了以下操作,但由于正在注入另一个服务类,我遇到了问题:( DiscountTierService 也被注入到 TieredClaimServiceImpl 中)
这是完整的示例:
@Service
public class TieredClaimServiceImpl implements TieredClaimService {
//@Autowired
private MerchRepository merchRepository;
//@Autowired
private SalesRepository salesRepository;
@Autowired
private DiscountTierService discountTierService;
private static final Logger LOGGER = LoggerFactory.getLogger(TieredClaimServiceImpl.class);
public TieredClaimServiceImpl() {
}
@Autowired
public TieredClaimServiceImpl(MerchRepository merchRepository,SalesRepository salesRepository) {
this.merchRepository = merchRepository;
this.salesRepository = salesRepository;
}
@Override
//public List<? extends MerchSales> calculateClaim(String code,LocalDate fromDate,LocalDate toDate) {
public List <TieredClaimDto> calculateClaim(ClaimRequestDto claimRequestDto,String xAppCorelationId) throws SystemException {
Run Code Online (Sandbox Code Playgroud)
这是修改后的测试类:
@ExtendWith(SpringExtension.class)
class TieredClaimServiceTest {
private TieredClaimService tieredClaimService;
@MockBean
private SalesRepository salesRepository;
@MockBean
private MerchRepository merchRepository;
@BeforeEach
void setUp() {
tieredClaimService = new
TieredClaimServiceImpl(merchRepository,salesRepository);
}
//@Autowired
//private DiscountTierService discountTierService;
@ParameterizedTest
@ValueSource(strings = {"merch", "sales"})
@DisplayName("xyz ")
void tieredClaimPositiveScenarioWithinTier(String sourceType) throws Exception {
Run Code Online (Sandbox Code Playgroud)
在实际的服务类中,我得到了注入,因为 DiscountTierService 没有被注入:
我在以下代码行中得到了 NPE:
@Override
public List <TieredClaimDto> calculateClaim(ClaimRequestDto claimRequestDto,String xAppCorelationId) throws SystemException {
/** get the discount tier config data **/
**List<DiscountTierDto> discountTierList = discountTierService.get();**
Run Code Online (Sandbox Code Playgroud)
小智 2
对于您的服务层,您不需要使用/不需要弹簧片。您只需使用 JUnit 测试您的 service.class 并使用 Mockito 模拟存储库,就像您在控制器中使用服务所做的那样。
如果您需要 SpringContext,您还可以使用 @RunWith(MockitoJUnitRunner.class) 或 @RunWith(SpringRunner.class) 注释您的测试类...
| 归档时间: |
|
| 查看次数: |
1900 次 |
| 最近记录: |