有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java spring引导用于测试服务组件的“切片”

我正在使用SpringBoot开发RESTAPI。 它由标准层组成:控制器(@RestController)(处理传入的http请求并公开api端点),然后是服务层(@service),最后是存储库层(@Repository)

我的问题是关于单元测试

为了测试我的控制器,我正在使用mockito模拟对服务层的调用。 为了防止不必要地加载整个上下文,我读了一些关于“SpringSlices”的文章 因此,为了测试我的控制器-这是使用的注释:

@WebMvcTest

@ExtendWith(SpringExtension.class)

@WebMvcTest(controllers = TieredClaimController.class)
class TieredClaimControllerTest {

    @MockBean
    private TieredClaimService tieredClaimService;

    @Autowired
    private MockMvc mockMvc;

类似地,为了测试我的spring数据存储库,使用了另一个spring切片注释:@DataJpaTest

@ExtendWith(SpringExtension.class)
@DataJpaTest

@ContextConfiguration(initializers = {SalesRepositoryTest.Initializer.class})
public class SalesRepositoryTest {  

    @Autowired
    private SalesRepository repository; 

因此,我可以看到专门针对Web端的事物(@WebMvcTest)和数据库端的事物(@DataJpaTest)的spring切片注释

然而,当我需要测试@Service注释类时,我应该使用哪个spring片? 我没有看到任何专门用于服务层的

我问的原因是我是这样使用它的: 注意(对存储库的调用是模拟的,因此本质上我的服务层单元测试是隔离的)

@ExtendWith(SpringExtension.class)
@SpringBootTest
class TieredClaimServiceTest {

    @Autowired
    private TieredClaimService tieredClaimService;  

    @MockBean
    private SalesRepository salesRepository;

然而问题是——当我运行这些单元测试时,会调用一些不必要的jpa/hibernate代码

我如何防止这种情况

2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | DEBUG | org.hibernate.SQL | drop table discount_tiers if exists Hibernate: drop table discount_tiers if exists 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | DEBUG | org.hibernate.SQL | drop table merch if exists Hibernate: drop table merch if exists 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | DEBUG | org.hibernate.SQL | drop table sales if exists Hibernate: drop table sales if exists 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | DEBUG | org.hibernate.SQL | drop table user if exists Hibernate: drop table user if exists 2019-11-29 | 21:04:17.309 | SpringContextShutdownHook | DEBUG | org.hibernate.SQL | drop sequence if exists hibernate_sequence Hibernate: drop sequence if exists hibernate_sequence*

2019-11-29 | 21:04:17.309 | SpringContextShutdownHook | DEBUG | o.h.t.s.TypeConfiguration$Scope | Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@89296ce] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@17fddecd]

我想这些会出现在日志中,因为在我的应用程序中。属性(在/src/test/resources下)我有:

spring.jpa.hibernate.ddl-auto=create-drop

但是,当我对存储库层进行单元测试时,我需要此配置,因此无法删除或删除它

那么对于我的服务层,是否有任何spring切片注释? 在测试与数据库/存储库隔离的服务层时,如何避免hibernate/jpa调用或加载,因为该层是模拟的

EDIT1: 根据下面的回答,我想我没有提供我的服务类别的完整细节: 我尝试了以下方法,但由于又注入了一个服务类,我遇到了一些问题:(DiscussionTierService也注入了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 {

以下是修订后的测试等级:

@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 {

在实际的服务类中,我得到了注入,因为DiscussionTierService没有被注入:

我在以下代码行获得NPE:

@Override
public List <TieredClaimDto>  calculateClaim(ClaimRequestDto claimRequestDto,String xAppCorelationId) throws SystemException {


    /** get the discount tier config data **/
    **List<DiscountTierDto> discountTierList = discountTierService.get();**

共 (1) 个答案

  1. # 1 楼答案

    对于您的服务层,您不需要使用spring片。 你测试你的服务。只需使用JUnit初始化,并使用Mockito模拟存储库,就像您在控制器中使用服务所做的那样

    如果需要SpringContext,还可以使用@RunWith(MockitoJUnitRunner.class)或@RunWith(SpringRunner.class)注释testclass