繁体   English   中英

Mockito when().thenReturn() 总是返回 null

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM