You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fabric8访问OpenShift CustomResource时如何编写Mock Junit测试

实现思路与示例代码

以下基于JUnit 5 + Mockito框架实现三类对象的Mock,可直接适配你现有的业务代码:

前置依赖

Maven项目需引入如下测试依赖:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>

Mock逻辑说明

  • Mock KubernetesClient:直接Mock接口即可,无需实例化真实的DefaultKubernetesClient
  • Mock MixedOperation:Mock对应泛型类型的MixedOperation对象,配置链式调用的返回规则:inNamespace()返回自身,withName()返回Mock的Resource对象
  • Mock CertificateRequest:直接构造或Mock该CRD类,按需设置元数据、spec等属性作为查询返回值

注意:建议你对原有业务代码做小改造,将KubernetesClient实例化逻辑抽离,通过方法入参或依赖注入的方式传入,避免直接在方法内new DefaultKubernetesClient,否则需要额外引入PowerMock才能Mock构造方法,不推荐这种方式。

完整测试示例

以测试你提供的业务逻辑为例,测试覆盖CertificateRequest存在和不存在两种场景:

import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.MixedOperation;
import io.fabric8.kubernetes.client.Resource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class CertificateRequestServiceTest {

    @Mock
    private KubernetesClient k8sClient;
    @Mock
    private MixedOperation<CertificateRequest, KubernetesResourceList<CertificateRequest>, Resource<CertificateRequest>> certClient;
    @Mock
    private Resource<CertificateRequest> certResource;
    @Mock
    private CertificateRequest mockCertificateRequest;

    // 测试场景:CertificateRequest已存在,验证delete方法被调用
    @Test
    void testCertRequestExists() {
        // 配置Mock规则
        when(k8sClient.resources(CertificateRequest.class)).thenReturn(certClient);
        when(certClient.inNamespace(anyString())).thenReturn(certClient);
        when(certClient.withName(anyString())).thenReturn(certResource);
        when(certResource.get()).thenReturn(mockCertificateRequest);

        // 调用你的业务方法,将Mock的k8sClient传入
        yourBusinessMethod(k8sClient, "test-namespace", "test-cert-request");

        // 验证delete方法执行了1次
        verify(certResource, times(1)).delete();
    }

    // 测试场景:CertificateRequest不存在,验证delete方法未被调用
    @Test
    void testCertRequestNotExists() {
        // 配置Mock规则
        when(k8sClient.resources(CertificateRequest.class)).thenReturn(certClient);
        when(certClient.inNamespace(anyString())).thenReturn(certClient);
        when(certClient.withName(anyString())).thenReturn(certResource);
        when(certResource.get()).thenReturn(null);

        // 调用你的业务方法,将Mock的k8sClient传入
        yourBusinessMethod(k8sClient, "test-namespace", "test-cert-request");

        // 验证delete方法未执行
        verify(certResource, never()).delete();
    }

    // 这是你改造后的业务方法,将k8sClient作为入参传入
    private void yourBusinessMethod(KubernetesClient k8sClient, String certNamespce, String certRequestName) {
        try (KubernetesClient client = k8sClient) {
            MixedOperation<
                    CertificateRequest,
                    KubernetesResourceList<CertificateRequest>,
                    Resource<CertificateRequest>>
                    certClient = client.resources(CertificateRequest.class);

            CertificateRequest certificateRequest =
                    certClient.inNamespace(certNamespce).withName(certRequestName).get();
            if (certificateRequest == null) {
                System.out.printf("CertificateRequest %s in certNamespce %s is a new one.%n",
                        certRequestName, certNamespce);
            } else {
                certClient.inNamespace(certNamespce).withName(certRequestName).delete();
                System.out.printf("Delete existing CertificateRequest %s in certNamespce %s, then create a new one.%n",
                        certRequestName, certNamespce);
            }
        } catch (Exception exception) {
            System.err.println("Hit an error when create a CertificateRequest: " + exception);
        }
    }
}

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:36:01