【问题标题】:call private method (PowerMockito Test)调用私有方法(PowerMockito Test)
【发布时间】:2022-01-25 19:26:19
【问题描述】:

首先执行save() 方法,该方法通过测试,直到达到一个条件,如果为真则调用saveBankAccountAndRole() 方法,如果为假则发送Mono.error(new Exception("...").

sizeAccounts(String customerId) 方法确实通过了测试。

saveBankAccountAndRole(BankAccountDto bnkDto)方法中,执行sizeAccounts()方法后,测试不通过,我漏了什么?

public Flux<BankAccountDto> findAccountsByCustomerId(String customerId) {
  return mongoRepository
          .findAll()
          .filter(ba ->
                  ba.getCustomerId().equals(customerId))
          .map(AppUtils::entityToDto);
}

private Mono<Long> sizeAccounts(String customerId){
  return findAccountsByCustomerId(customerId)
      .count();
}


private Mono<BankAccountDto> saveBankAccountAndRole(BankAccountDto bnkDto) {
  return sizeAccounts(bnkDto.getCustomerId())
    .flatMap(number -> {
      bnkDto.setOpeningOrder(number + 1);
      return mongoRepository.save(AppUtils.dtoToEntity(bnkDto))
          .switchIfEmpty(Mono.error(new Exception("Problem saving the bank account")))
          .zipWhen(bnk -> {
            var customerRoleDto = new CustomerRoleDto();
            customerRoleDto.setBankAccountId(bnk.getBankAccountId());
            customerRoleDto.setCustomerId(bnkDto.getCustomerId());
            customerRoleDto.setRoleType(bnkDto.getRoleType());

            return webClientRoleHelper.saveCustomerRole(customerRoleDto);
          })
          .switchIfEmpty(Mono.error(new Exception("Problem saving roles")))
          .map(tuple -> AppUtils.entityToDto(tuple.getT1()));
    });
}

测试:

@Mock
private IMongoBankAccountRepository mongoRepository;

@InjectMocks
private BankAccountServiceImpl bankAccountServiceImpl;    

@Test
void saveBankAccountAndRoleTest() throws Exception {
    when(mongoRepository.findAll()).thenReturn(Flux.just(bnkDto)
        .map(AppUtils::dtoToEntity));

    when(mongoRepository.findAll().filter(ba ->
        ba.getCustomerId().equals(customerId)))
        .thenReturn(Flux.just(bnkDto).map(AppUtils::dtoToEntity));

    StepVerifier.create(bankAccountServiceImpl.findAccountsByCustomerId(customerId))
        .expectSubscription()
        .expectNext(bnkDto)
        .verifyComplete();

    var spy = PowerMockito.spy(bankAccountServiceImpl);

    PowerMockito.when(spy, "sizeAccounts", customerId)
        .thenReturn(Mono.just(2L));
    PowerMockito.when(spy, "saveBankAccountAndRole",bnkDto)
        .thenReturn(Mono.just(bnkDto));
}

例外:

java.lang.AssertionError:预期“expectNext(com.nttdata.bootcamp.model.dto.BankAccountDto@147c4523)”失败(预期值:com.nttdata.bootcamp.model.dto.BankAccountDto@147c4523;实际值: com.nttdata.bootcamp.model.dto.BankAccountDto@551725e4) 在 com.nttdata.bootcamp.business.impl.BankAccountServiceImplTest.saveBankAccountAndRoleTest(BankAccountServiceImplTest.java:267)

verifyComplete() 时发送给我

【问题讨论】:

  • 你在BankAccountDto类中实现了toStringequals吗?
  • 不,但我只是放置了那些 lombok 注释并重新测试,它引发了另一个异常:org.mockito.exceptions.misusing.WrongTypeOfReturnValue: MonoJust cannot be returned by findAll() findAll() should return Flux。这导致了saveBankAccountAndRole 的 PowerMockito

标签: spring mockito spring-webflux powermockito


【解决方案1】:

通过查看测试中的代码,您不应期望返回特定对象。

when(mongoRepository.findAll()).thenReturn(Flux.just(bnkDto)
    .map(AppUtils::dtoToEntity));

when(mongoRepository.findAll().filter(ba ->
    ba.getCustomerId().equals(customerId)))
    .thenReturn(Flux.just(bnkDto).map(AppUtils::dtoToEntity));

上面的代码将该 DTO 对象映射到一个实体,这对存储库很有意义。但是,这意味着以下代码会将其“重新映射”到新创建的对象:

.zipWhen(bnk -> {
     var customerRoleDto = new CustomerRoleDto();
     customerRoleDto.setBankAccountId(bnk.getBankAccountId());
     customerRoleDto.setCustomerId(bnkDto.getCustomerId());
     customerRoleDto.setRoleType(bnkDto.getRoleType());

     return webClientRoleHelper.saveCustomerRole(customerRoleDto);
 })

因此,您应该期待一个具有相同类的对象,包含相同实例的变量值。但你不能指望它是完全相同的对象。

您可能想试试这个(未经测试的代码):

StepVerifier.create(bankAccountServiceImpl.findAccountsByCustomerId(customerId))
    .expectSubscription()
    .expectMatches(dto ->     dto.getBankAccountId().equals(bankDto.getBankAccountId) &&     dto.getCustomerId.equals(bnkDto.getCustomerId))
    .verifyComplete();

我希望这对你有用。

【讨论】:

    猜你喜欢
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    相关资源
    最近更新 更多