From 81defc835fcad40bd5c7f1a5bcedb36af8055dcc Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Sun, 8 Mar 2026 20:26:40 -0700 Subject: [PATCH] refactor: replace testutil.WithEnvVar with t.Setenv (#479) t.Setenv is the modern standard Go testing utility (since Go 1.17) that automatically restores environment variables when the test completes. This replaces the custom testutil.WithEnvVar function which manually saved and restored env var state. The testutil.go file is deleted as it only contained WithEnvVar. The testutil package remains for its other utilities like KubeconfigBuilder. --- cmd/kubens/statefile_test.go | 6 ++-- internal/cmdutil/util_test.go | 8 +---- internal/kubeconfig/kubeconfigloader_test.go | 17 +++++------ internal/printer/color_test.go | 12 ++++---- internal/testutil/testutil.go | 31 -------------------- 5 files changed, 16 insertions(+), 58 deletions(-) delete mode 100644 internal/testutil/testutil.go diff --git a/cmd/kubens/statefile_test.go b/cmd/kubens/statefile_test.go index 271ffab..96499dd 100644 --- a/cmd/kubens/statefile_test.go +++ b/cmd/kubens/statefile_test.go @@ -18,8 +18,6 @@ import ( "runtime" "strings" "testing" - - "github.com/ahmetb/kubectx/internal/testutil" ) func TestNSFile(t *testing.T) { @@ -50,7 +48,7 @@ func TestNSFile(t *testing.T) { } func TestNSFile_path_windows(t *testing.T) { - defer testutil.WithEnvVar("_FORCE_GOOS", "windows")() + t.Setenv("_FORCE_GOOS", "windows") fp := NewNSFile("a:b:c").path() if expected := "a__b__c"; !strings.HasSuffix(fp, expected) { @@ -68,7 +66,7 @@ func Test_isWindows(t *testing.T) { t.Fatalf("isWindows() returned true for %s", runtime.GOOS) } - defer testutil.WithEnvVar("_FORCE_GOOS", "windows")() + t.Setenv("_FORCE_GOOS", "windows") if !isWindows() { t.Fatalf("isWindows() failed to detect windows with env override.") } diff --git a/internal/cmdutil/util_test.go b/internal/cmdutil/util_test.go index 78ceb32..e4368a3 100644 --- a/internal/cmdutil/util_test.go +++ b/internal/cmdutil/util_test.go @@ -17,8 +17,6 @@ package cmdutil import ( "path/filepath" "testing" - - "github.com/ahmetb/kubectx/internal/testutil" ) func Test_homeDir(t *testing.T) { @@ -64,18 +62,14 @@ func Test_homeDir(t *testing.T) { for _, c := range cases { t.Run(c.name, func(tt *testing.T) { - var unsets []func() for _, e := range c.envs { - unsets = append(unsets, testutil.WithEnvVar(e.k, e.v)) + tt.Setenv(e.k, e.v) } got := HomeDir() if got != c.want { t.Errorf("expected:%q got:%q", c.want, got) } - for _, u := range unsets { - u() - } }) } } diff --git a/internal/kubeconfig/kubeconfigloader_test.go b/internal/kubeconfig/kubeconfigloader_test.go index 348f320..8f16c8b 100644 --- a/internal/kubeconfig/kubeconfigloader_test.go +++ b/internal/kubeconfig/kubeconfigloader_test.go @@ -15,17 +15,16 @@ package kubeconfig import ( - "github.com/ahmetb/kubectx/internal/cmdutil" "os" "path/filepath" "strings" "testing" - "github.com/ahmetb/kubectx/internal/testutil" + "github.com/ahmetb/kubectx/internal/cmdutil" ) func Test_kubeconfigPath(t *testing.T) { - defer testutil.WithEnvVar("HOME", "/x/y/z")() + t.Setenv("HOME", "/x/y/z") expected := filepath.FromSlash("/x/y/z/.kube/config") got, err := kubeconfigPath() @@ -38,9 +37,9 @@ func Test_kubeconfigPath(t *testing.T) { } func Test_kubeconfigPath_noEnvVars(t *testing.T) { - defer testutil.WithEnvVar("XDG_CACHE_HOME", "")() - defer testutil.WithEnvVar("HOME", "")() - defer testutil.WithEnvVar("USERPROFILE", "")() + t.Setenv("XDG_CACHE_HOME", "") + t.Setenv("HOME", "") + t.Setenv("USERPROFILE", "") _, err := kubeconfigPath() if err == nil { @@ -49,7 +48,7 @@ func Test_kubeconfigPath_noEnvVars(t *testing.T) { } func Test_kubeconfigPath_envOvveride(t *testing.T) { - defer testutil.WithEnvVar("KUBECONFIG", "foo")() + t.Setenv("KUBECONFIG", "foo") v, err := kubeconfigPath() if err != nil { @@ -62,7 +61,7 @@ func Test_kubeconfigPath_envOvveride(t *testing.T) { func Test_kubeconfigPath_envOvverideDoesNotSupportPathSeparator(t *testing.T) { path := strings.Join([]string{"file1", "file2"}, string(os.PathListSeparator)) - defer testutil.WithEnvVar("KUBECONFIG", path)() + t.Setenv("KUBECONFIG", path) _, err := kubeconfigPath() if err == nil { @@ -71,7 +70,7 @@ func Test_kubeconfigPath_envOvverideDoesNotSupportPathSeparator(t *testing.T) { } func TestStandardKubeconfigLoader_returnsNotFoundErr(t *testing.T) { - defer testutil.WithEnvVar("KUBECONFIG", "foo")() + t.Setenv("KUBECONFIG", "foo") kc := new(Kubeconfig).WithLoader(DefaultLoader) err := kc.Parse() if err == nil { diff --git a/internal/printer/color_test.go b/internal/printer/color_test.go index 9991c72..4e1cd1f 100644 --- a/internal/printer/color_test.go +++ b/internal/printer/color_test.go @@ -18,8 +18,6 @@ import ( "testing" "github.com/google/go-cmp/cmp" - - "github.com/ahmetb/kubectx/internal/testutil" ) var ( @@ -27,8 +25,8 @@ var ( ) func Test_useColors_forceColors(t *testing.T) { - defer testutil.WithEnvVar("_KUBECTX_FORCE_COLOR", "1")() - defer testutil.WithEnvVar("NO_COLOR", "1")() + t.Setenv("_KUBECTX_FORCE_COLOR", "1") + t.Setenv("NO_COLOR", "1") if v := useColors(); !cmp.Equal(v, &tr) { t.Fatalf("expected useColors() = true; got = %v", v) @@ -36,7 +34,7 @@ func Test_useColors_forceColors(t *testing.T) { } func Test_useColors_disableColors(t *testing.T) { - defer testutil.WithEnvVar("NO_COLOR", "1")() + t.Setenv("NO_COLOR", "1") if v := useColors(); !cmp.Equal(v, &fa) { t.Fatalf("expected useColors() = false; got = %v", v) @@ -44,8 +42,8 @@ func Test_useColors_disableColors(t *testing.T) { } func Test_useColors_default(t *testing.T) { - defer testutil.WithEnvVar("NO_COLOR", "")() - defer testutil.WithEnvVar("_KUBECTX_FORCE_COLOR", "")() + t.Setenv("NO_COLOR", "") + t.Setenv("_KUBECTX_FORCE_COLOR", "") if v := useColors(); v != nil { t.Fatalf("expected useColors() = nil; got=%v", *v) diff --git a/internal/testutil/testutil.go b/internal/testutil/testutil.go deleted file mode 100644 index 6244c07..0000000 --- a/internal/testutil/testutil.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package testutil - -import "os" - -// WithEnvVar sets an env var temporarily. Call its return value -// in defer to restore original value in env (if exists). -func WithEnvVar(key, value string) func() { - orig, ok := os.LookupEnv(key) - os.Setenv(key, value) - return func() { - if ok { - os.Setenv(key, orig) - } else { - os.Unsetenv(key) - } - } -}