我有以下服务:
@Service
@RequiredArgsConstructor
public class LimitService {
private final CoreService coreService;
private final AuditService audit;
public Limit get(User user) {
Limit limit = coreService.get(user);
if (limit != null) {
Optional.ofNullable(limit.getAvailable())
.map(String::valueOf)
.map(BigDecimal::new)
.map(availableValue -> availableValue.setScale(2, RoundingMode.HALF_DOWN))
.map(BigDecimal::doubleValue)
.ifPresentOrElse(val -> limit.setAvailable(val), () -> limit.setAvailable(0d));
}
return limit;
}
}
以及以下相关测试
@ExtendWith(MockitoExtension.class)
public class LimitServiceTest {
@Mock
private CoreService coreService;
@Mock
private AuditService audit;
@InjectMocks
private LimitService service;
@BeforeEach
public void init(){
MockitoAnnotations.openMocks(this);
}
@Test
public void shouldReturnNull(){
assertThat(this.service.get(new User())).isNull();
}
@Test
public void shouldSetToZero_whenNull(){
User user = new User();
Mockito.when(this.coreService.get(any(User.class)))
.thenReturn(new Limit());
assertThat(this.service.get(user)).extracting(Limit::getAvailable)
.isEqualTo(0d);
}
}
当我在调试模式下运行第二个测试时,我可以看到实际上为CoreService生成了一个mock,但是Mockito似乎忽略了when..thenReturn。
我也尝试过使用eq(user)而不是any(User.class),但结果是一样的。我在另一个项目中做了类似的测试,一切都很好。我不知道为什么在这种情况下不起作用。
1条答案
按热度按时间lf5gs5x21#
@InjectMocks
首先运行(由MockitoExtension
执行),并将mock示例分配给带注解的LimitService
字段中的字段。稍后,
openMocks
创建第二组模拟示例,并将它们分配给测试中的字段(但不会重新分配服务的字段)。服务仍将引用扩展创建的模拟示例。这可以通过在调用
openMocks
之前和之后打印字段的标识散列代码来验证:(This需要暂时使
LimitService#coreService
字段可访问)。示例输出:现在调用
when
为第二个mock示例设置存根,但是您的服务不知道这个示例,因为它只保存了对第一个mock示例的引用。这个问题和相关问题在Why is my class not calling my mocked methods in unit test?的答案中讨论。