【问题标题】:unit test Spring boot service class that has dependency on another service class单元测试依赖于另一个服务类的 Spring Boot 服务类
【发布时间】:2019-12-02 20:56:49
【问题描述】:

我正在编写一个 Spring Boot Rest 服务,在该服务中尝试对使用 @Service 注释的类进行单元测试。 此服务类在内部使用另一个服务类。 这是代码:

@Service
public class TieredClaimServiceImpl implements TieredClaimService {

//this is the second service used within 
// commented out setter injection and used constructor injection 
// @Autowired
private DiscountTierService discountTierService;

@Autowired
public TieredClaimServiceImpl(MerchRepository merchRepository,SalesRepository 
         salesRepository,DiscountTierService discountTierService) {
    this.merchRepository = merchRepository;
    this.salesRepository = salesRepository;
    this.discountTierService = discountTierService;
}

这是我需要进行单元测试的类中的方法:

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

    /** get the discount tier config data  - this is where we are using the other service **/
    List<DiscountTierDto> discountTierList = discountTierService.get();

我想模拟在“TieredClaimServiceImpl”中使用的“DiscountTierService”

在我的单元测试课程中,我尝试模拟对该服务的调用:

DiscountTierService discountTierService = mock(DiscountTierService.class);

DiscountTierService discountTierService = spy(new DiscountTierServiceImpl());

这些都不起作用。

虽然没有直接关系,但我有一个与整个解决方案相关的问题here

【问题讨论】:

  • 你的单元测试是什么样子的?你是如何创建 TieredClaimServiceImpl 的——你是在启动整个 spring 上下文以将它们创建为 bean,还是使用 new 在没有上下文的情况下手动创建?
  • Mocking 是这里的合适工具。请解释“没用”。

标签: java spring spring-boot unit-testing mocking


【解决方案1】:

您说的是单元测试,但试图创建集成测试

@SpringBootTest
@ActiveProfules(value = "test")//or @TestPropertySource(s)
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SomeTestConfiguration.class})
public class SomeTestClass {

    @Autowired//or @Mock
    private MerchRepository merchRepository;

    @Autowired//or @Mock
    private SalesRepository salesRepository;

    @Mock
    private DiscountTierService discountTierService;

    private TieredClaimService service;

    @Before
    public void setup() {
        service = new TieredClaimServiceImpl(merchRepository, salesRepository, discountTierService);
    }

    @Test
    public void test() {
        //arrange
        var dto1 = new DiscountTierDto(...);
        var dto2 = new DiscountTierDto(...);
        var someList = List.of(dto1, dto2);
        when(discountTierService.get()).thenReturn(someList);
        //act
        service.calculateClaim(someClaimRequestDto, someAppCorrelationId);
        //assert
        Assert.assertThat(...);
    }
}

如果你真的想创建一个单元测试,你不需要大多数类注解,只需要@RunWith,并在必要时设置测试属性(当然,在这种情况下,你不能自动装配存储库,只是模拟)。

但是,如果您正在查看将调用调用服务的控制器方法的集成测试,则需要使用独立控制器创建 MockMvc 对象。而创建控制器对象只需设置此服务配置 - 在这种情况下,您可以控制所有需要的嵌套对象(服务、嵌套服务、存储库)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2022-01-08
    • 2020-12-09
    相关资源
    最近更新 更多