我有一个单元测试,看起来像这样:
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")));
和一个gradle依赖项,看起来像:
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
compile 'info.picocli:picocli:4.2.0'
compile 'org.yaml:snakeyaml:1.26'
// Use JUnit test framework
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.5.2")
testRuntime("org.junit.platform:junit-platform-runner:1.5.2")
testImplementation('org.junit.jupiter:junit-jupiter:5.5.2')
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation "org.mockito:mockito-core:2.+"
compile 'io.swagger.parser.v3:swagger-parser:2.0.19'
compile 'org.cloudfoundry:cloudfoundry-client-reactor:4.6.0.RELEASE'
compile 'org.cloudfoundry:cloudfoundry-operations:4.6.0.RELEASE'}
当我尝试执行此测试时, 我收到:
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(...))
有人有一个主意,如何测试它,或者应该如何调整代码? 我花了很多时间,但找不到解决方案,对我来说真的很有效。
谢谢
答案 0 :(得分:1)
在生产代码中(与测试代码相反),不要使用DefaultCloudFoundryOperations
,而要使用它实现的接口:CloudFoundryOperations
例如,这样声明:
public class SpaceDevelopersProvider {
private final CloudFoundryOperations cfOps;
public SpaceDevelopersProvider(CloudFoundryOperations cfOps) {
this.cfOps = cfOps;
}
...
}
然后,您可以模拟该界面。
CloudFoundryOperations cfOperationsMock = mock(CloudFoundryOperations.class);
...
SpaceDevelopersProvider spaceDeveloperProvider = new SpaceDevelopersProvider(cfOperationsMock);
答案 1 :(得分:0)
在运行时,当您使用Mockito模拟对象时,它将创建一个代理类并扩展您要模拟的类。像在Java中一样,最终类无法扩展,因此嘲笑无法模拟最终类。
答案 2 :(得分:0)
从类名(DefaultCloudFoundryOperations
)中,我会 猜 ,首先,该类实现一个接口,其次,所有使用者都将采用该接口界面,而不是具体的类。
如果我 会 对,那么您可以模拟该接口,而不是具体的类。
如上所述,这是一个猜测!