无法在Java中模拟最终类

无法在Java中模拟最终类,java,testing,mockito,static-classes,Java,Testing,Mockito,Static Classes,我有一个单元测试,看起来是这样的: DefaultCloudFoundryOperations cfOperationsMock = mock(DefaultCloudFoundryOperations.class); when(cfOperationsMock.getSpace()).thenReturn("development"); when(cfOperationsMock.getOrganization()).thenReturn("cloud.foun

我有一个单元测试,看起来是这样的:

DefaultCloudFoundryOperations cfOperationsMock = mock(DefaultCloudFoundryOperations.class);
        when(cfOperationsMock.getSpace()).thenReturn("development");
        when(cfOperationsMock.getOrganization()).thenReturn("cloud.foundry.cli");

        UserAdmin userAdminMock = mock(UserAdmin.class);
        when(cfOperationsMock.userAdmin()).thenReturn(userAdminMock);

        Mono<SpaceUsers> monoMock = (Mono<SpaceUsers>) mock(Mono.class);
        when(userAdminMock.listSpaceUsers(any())).thenReturn(monoMock);

        SpaceUsers spaceUsersMock = mock(SpaceUsers.class);
        when(monoMock.block()).thenReturn(spaceUsersMock);
        when(spaceUsersMock.getDevelopers())
            .thenReturn(Arrays.asList("one", "two", "three", "four"));

        SpaceDevelopersProvider spaceDeveloperProvider = new SpaceDevelopersProvider(
            cfOperationsMock);

        String spaceDevelopers = spaceDeveloperProvider.getSpaceDevelopers();

        assertThat(spaceDevelopers, is(Arrays.asList("one", "two", "three", "four")));
当我尝试执行此测试时, 我收到:

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class org.cloudfoundry.operations.DefaultCloudFoundryOperations.
Can not mock final classes with the following settings :
 - explicit serialization (e.g. withSettings().serializable())
 - extra interfaces (e.g. withSettings().extraInterfaces(...))
是否有人有想法,我如何测试它,或者我应该如何调整代码? 我花了很多时间,但无法找到一个真正适合我的解决方案


谢谢

在运行时,当您使用Mockito模拟对象时,它将创建一个代理类并扩展您要模拟的类。与java中一样,final类不能扩展,因此mockito不能模拟final类。

在生产代码中(与测试代码相反),不要使用
DefaultCloudFoundryOperations
,而是使用它实现的接口:

例如,声明如下:

public class SpaceDevelopersProvider {
  private final CloudFoundryOperations cfOps;
  public SpaceDevelopersProvider(CloudFoundryOperations cfOps) {
    this.cfOps = cfOps;
  }
  ...
}
然后,您可以模拟该接口

CloudFoundryOperations cfOperationsMock = mock(CloudFoundryOperations.class);
...
SpaceDevelopersProvider spaceDeveloperProvider = new SpaceDevelopersProvider(cfOperationsMock);

从类的名称(
DefaultCloudFoundryOperations
)我猜,首先类实现了一个接口,其次,所有使用者都将使用该接口,而不是具体的类

如果I是正确的,那么可以模拟接口而不是具体类


如前所述,这是一个猜测CloudFoundryOperations cfOperationsMock = mock(CloudFoundryOperations.class); ... SpaceDevelopersProvider spaceDeveloperProvider = new SpaceDevelopersProvider(cfOperationsMock);