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

Fabric8:未设置'expect'时Mock Kubernetes Server无法创建资源

问题分析与解决方案

首先明确:@EnableKubernetesMockClient启用的KubernetesMockServer并非自动支持CRUD持久化的模拟服务,它本质是请求匹配式的mock工具——所有API请求都需要预先定义对应的预期响应,否则会返回404(Not Found)。你的错误就来自于没有为POST /apis/batch/v1/namespaces/test/jobs这个创建Job的请求设置预期响应。

两种可行解决思路

思路1:使用支持自动CRUD的本地嵌入式K8s服务器

如果你想要无需手动模拟每个请求、自动处理资源CRUD的测试环境,应该使用fabric8提供的LocalKubernetesServer,而非KubernetesMockServer。

配置示例如下:

import io.fabric8.kubernetes.api.model.batch.Job;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.server.local.LocalKubernetesServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Test {

    private static LocalKubernetesServer server;
    private static KubernetesClient client;

    @BeforeAll
    static void setup() {
        server = new LocalKubernetesServer();
        server.start();
        client = server.getClient();
    }

    @AfterAll
    static void teardown() {
        client.close();
        server.stop();
    }

    @Test
    public void test_create_custom_job() {
        MyJobDetails myJobDetails = new MyJobDetails();
        String jobName = "job1-202211200345-prod";
        myJobDetails.setName(jobName);
        // 其他属性设置...

        PlatformOperationsService svc = new PlatformOperationsService(client);
        svc.createCustomJob(myJobDetails);

        // 直接查询已创建的Job
        Job createdJob = client.batch().v1().jobs().list().getItems().get(0);
        assertEquals(jobName, createdJob.getMetadata().getName());
        // 其他断言...
    }
}

这个本地服务器会模拟真实K8s的CRUD行为,自动存储你创建的资源,无需手动设置请求预期。

思路2:为MockServer预先设置请求预期

如果必须使用KubernetesMockServer,需要为每个API请求(包括创建和查询)定义预期响应:

import io.fabric8.kubernetes.api.model.batch.Job;
import io.fabric8.kubernetes.api.model.batch.JobBuilder;
import io.fabric8.kubernetes.api.model.batch.JobListBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

@EnableKubernetesMockClient
public class Test {

    KubernetesMockServer server;
    KubernetesClient client;

    @Test
    public void test_create_custom_job() {
        MyJobDetails myJobDetails = new MyJobDetails();
        String jobName = "job1-202211200345-prod";
        myJobDetails.setName(jobName);
        // 其他属性设置...

        // 1. 预先设置创建Job的请求预期
        Job mockJob = new JobBuilder()
                .withNewMetadata()
                .withName(jobName)
                .withNamespace("test")
                .endMetadata()
                // 匹配你的实际Job spec
                .withNewSpec()
                .endSpec()
                .build();

        server.expect().post().withPath("/apis/batch/v1/namespaces/test/jobs")
                .andReturn(201, mockJob)
                .once();

        // 2. 预先设置查询Job列表的请求预期
        server.expect().get().withPath("/apis/batch/v1/namespaces/test/jobs")
                .andReturn(200, new JobListBuilder().addItems(mockJob).build())
                .once();

        PlatformOperationsService svc = new PlatformOperationsService(client);
        svc.createCustomJob(myJobDetails);

        Job createdJob = client.batch().v1().jobs().list().getItems().get(0);
        assertEquals(jobName, createdJob.getMetadata().getName());
        // 其他断言...
    }
}

这种方式需要你为每个API交互都定义预期,适合需要精确控制请求响应的场景,但不符合你“无需模拟PUT/POST操作”的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:55:27