[英]Mockito when().thenReturn() returns always null
我有以下服务:
@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 生成了一个模拟,但 Mockito 似乎忽略了 when..thenReturn。
我也尝试过使用 eq(user) 而不是 any(User.class),但结果是一样的。 我在另一个项目中进行了类似的测试,一切正常。 我不知道为什么这在这种情况下不起作用..
@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);
}
// ...
@InjectMocks
首先运行(由MockitoExtension
执行)并将模拟实例分配给带注释的LimitService
字段中的字段。
稍后, openMocks
创建第二组模拟实例并将它们分配给测试中的字段(但不会重新分配服务的字段)。 该服务仍将引用扩展创建的模拟实例。
这可以通过在调用openMocks
之前和之后打印字段的标识 hash 代码来验证:
@BeforeEach
public void init(){
System.err.println("@InjectMocks:");
System.err.println(System.identityHashCode(coreService));
System.err.println(System.identityHashCode(service.coreService));
MockitoAnnotations.openMocks(this);
System.err.println("openMocks(this):");
System.err.println(System.identityHashCode(coreService));
System.err.println(System.identityHashCode(service.coreService));
}
(这需要暂时使LimitService#coreService
字段可访问)。 示例 output:
@InjectMocks:
763677574
763677574
openMocks(this):
234857227
763677574
调用when
现在为第二个模拟实例设置存根,但您的服务不知道这个实例,因为它只持有对第一个模拟实例的引用。
这个问题和相关问题在为什么我的 class 不在单元测试中调用我的模拟方法? .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.