View Source Kubereq.Kubeconfig.Stub (kubereq v0.1.7)

Req testing conveniences for kubereq requests.

Since kubereq is using Req under the hood, we can use Req.Test to run requests through mocks/stubs. Using this step as your Kubeconfig pipeline, you can set a stub on the Req.Request configured by this step.

In your tests, you can then use Req.Test according to its documentation.

Example

Imagine we're building an app with a pod client that lists pods on the cluster.

We start off by defining a module for loading the Kubernetes config:

defmodule MyApp.Kubeconfig do
  @kubeconfig_pipeline Application.compile_env(:myapp, :kubeconfig_pipeline)

  def load(), do: Kubereq.Kubeconfig.load(@kubeconfig_pipeline)
end

We then implement the pod client using the Kubeconfig loader to create a Req.Request:

defmodule MyApp.PodClient do
  @resource_path "api/v1/namespaces/:namespace/pods/:name"

  def list(namespace) do
    req = Kubereq.new(MyApp.Kubeconfig.load(), @resource_path)

    {:ok, resp} = Kubereq.list(req, namespace)
    resp.body["items"]
  end
end

We configure the kubeconfig pipeline for production using Kubereq.Kubeconfig.Default as our pipeline to load the Kubeconfig:

# config/prod.exs
config :myapp, kubeconfig_pipeline: Kubereq.Kubeconfig.Default

In tests, instead of sending requests to the cluster, we make the request against a plug stub named MyApp.Cluster:

# config/test.exs
config :myapp, kubeconfig_pipeline: {Kubereq.Kubeconfig.Stub, plugs: {Req.Test, MyApp.Cluster}}

Now we can control our stubs in concurrent tests:

use ExUnit.Case, async: true

test "many pods" do
  Req.Test.stub(MyApp.Cluster, fn conn ->
    Req.Test.json(conn, %{
      "apiVersion" => "v1",
      "kind" => "List",
      "items" => [
        %{
          "apiVersion" => "v1",
          "kind" => "Pod"
          # ...
        }
      ]
    })
  end)

  assert [_] = MyApp.PodClient.list("default")
end

Stubs per Context

If you want to simulate multiple different clusters or different responses for the same calls, you can pass a %{context :: String.t() => plug :: tuple} map to as plugs option.

# config/test.exs
config :myapp, kubeconfig_pipeline: {Kubereq.Kubeconfig.Stub, plugs: %{
  "happy-path" => {Req.Test, MyApp.HappyPathCluster}
  "missing-permissions" => {Req.Test, MyApp.MissingPermissionsCluster}
}}

Options

  • plugs - The plug or %{context => plug} map to be configured on the Req.Request configured by this step.