Skip to content

Instantly share code, notes, and snippets.

@mmierzwa
Created November 6, 2024 21:01
Show Gist options
  • Save mmierzwa/fe0d5ffbac47e8c22686d0b6f7c3bd5d to your computer and use it in GitHub Desktop.
Save mmierzwa/fe0d5ffbac47e8c22686d0b6f7c3bd5d to your computer and use it in GitHub Desktop.
golang viper testing
package config
import (
"fmt"
"os"
"strings"
"github.com/spf13/viper"
)
type Configuration struct {
Database struct {
Host string `mapstructure:"HOST"`
Port int `mapstructure:"PORT"`
} `mapstructure:"DB"`
WasInitializedWithDefaults bool `mapstructure:"WAS_INITIALIZED_WITH_DEFAULTS"`
}
func Load(config *Configuration) error {
viper.SetConfigType("env")
fmt.Printf("env: %v", os.Environ())
viper.SetEnvKeyReplacer(strings.NewReplacer(`.`, `_`))
viper.AutomaticEnv()
err := viper.Unmarshal(config)
if err != nil {
return fmt.Errorf("unable to decode into configuration struct: %w", err)
}
return nil
}
package config_test
import (
"fmt"
"os"
"testing"
"crm-v2/internal/config"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
)
func newTestConfig(host string, port int, wasInitializedWithDefaults bool) *config.Configuration {
return &config.Configuration{
Database: struct {
Host string `mapstructure:"HOST"`
Port int `mapstructure:"PORT"`
}{
Host: host,
Port: port,
},
WasInitializedWithDefaults: wasInitializedWithDefaults,
}
}
func TestLoad(t *testing.T) {
testCases := map[string]struct {
setupEnvironment func()
expectedConfig *config.Configuration
expectedError error
}{
"initiates config": {
setupEnvironment: func() {
require.NoError(t, os.Setenv("DB_HOST", "test-hostname"))
require.NoError(t, os.Setenv("DB_PORT", "5432"))
},
expectedConfig: newTestConfig("test-hostname", 5432, true),
},
"handles unmarshal error": {
setupEnvironment: func() {
require.NoError(t, os.Setenv("DB_HOST", "test-hostname"))
require.NoError(t, os.Setenv("DB_PORT", "test-password"))
require.NoError(t, os.Setenv("WAS_INITIALIZED_WITH_DEFAULTS", "foo-bar"))
},
expectedConfig: &config.Configuration{},
expectedError: fmt.Errorf("unable to decode into configuration struct: "),
},
}
for testName, testCase := range testCases {
t.Run(testName, func(t *testing.T) {
cfg := &config.Configuration{}
testCase.setupEnvironment()
err := config.Load(cfg)
if testCase.expectedError != nil {
assert.ErrorContains(t, err, testCase.expectedError.Error())
} else {
assert.NoError(t, err)
assert.Equal(t, testCase.expectedConfig, cfg)
}
})
}
}
/opt/homebrew/opt/go/libexec/bin/go tool test2json -t /Users/tharnendil/Library/Caches/JetBrains/GoLand2024.2/tmp/GoLand/___TestLoad_in_crm_v2_internal_config.test -test.v=test2json -test.paniconexit0 -test.run ^\QTestLoad\E$
=== RUN TestLoad
=== RUN TestLoad/initiates_config
env: [PATH=/Users/tharnendil/bin:/Users/tharnendil/Tools:/Users/tharnendil/Documents/go/bin:/Users/tharnendil/.nvm/versions/node/v22.6.0/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/tharnendil/.cache/zsh4humans/v5/fzf/bin:/Users/tharnendil/Library/Application Support/JetBrains/Toolbox/scripts:/opt/homebrew/opt/go/libexec/bin:/Users/tharnendil/Documents/go/bin MANPATH=/Users/tharnendil/.nvm/versions/node/v22.6.0/share/man:/opt/homebrew/share/man:/usr/share/man:/usr/local/share/man:/Users/tharnendil/.cache/zsh4humans/v5/fzf/man: TREE_COLORS=fi=00:mi=00:mh=00:ln=01;36:or=01;31:di=01;34:ow=01;34:st=34:tw=34:pi=01;33:so=01;33:do=01;33:bd=01;33:cd=01;33:su=01;35:sg=01;35:ca=01;35:ex=01;32 TERM=xterm-256color HOMEBREW_PREFIX=/opt/homebrew COMMAND_MODE=unix2003 SSH_AGENT_PID=81171 NVM_INC=/Users/tharnendil/.nvm/versions/node/v22.6.0/include/node LOGNAME=tharnendil HOMEBREW_REPOSITORY=/opt/homebrew XPC_SERVICE_NAME=application.com.jetbrains.goland.6031950.6031959 PWD=/Users/tharnendil/Repos/common/crm-v2/internal/config INFOPATH=/opt/homebrew/share/info: __CFBundleIdentifier=com.jetbrains.goland NVM_CD_FLAGS=-q SHELL=/bin/zsh NVM_DIR=/Users/tharnendil/.nvm PAGER=less TERMINFO=/Users/tharnendil/.terminfo LSCOLORS=ExGxDxDxCxDxDxFxFxexEx OLDPWD=/ HOMEBREW_CELLAR=/opt/homebrew/Cellar GPG_TTY=not a tty GOPATH=/Users/tharnendil/Documents/go GO15VENDOREXPERIMENT=1 USER=tharnendil GOROOT=/opt/homebrew/opt/go/libexec TMPDIR=/var/folders/h6/_h318_2j7msg73wp9q_1rqrh0000gn/T/ GO111MODULE=on SSH_AUTH_SOCK=/var/folders/h6/_h318_2j7msg73wp9q_1rqrh0000gn/T//ssh-770nQaV1bHHK/agent.81170 XPC_FLAGS=0x0 LC_ALL=en_US.UTF-8 __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0 LESS=-iRFXMx4 LS_COLORS=fi=00:mi=00:mh=00:ln=01;36:or=01;31:di=01;34:ow=04;01;34:st=34:tw=04;34:pi=01;33:so=01;33:do=01;33:bd=01;33:cd=01;33:su=01;35:sg=01;35:ca=01;35:ex=01;32 NVM_BIN=/Users/tharnendil/.nvm/versions/node/v22.6.0/bin HOME=/Users/tharnendil GOARCH=arm64 GOCACHE=/Users/tharnendil/Library/Caches/go-build GOENV=/Users/tharnendil/Library/Application Support/go/env GOHOSTARCH=arm64 GOHOSTOS=darwin GOMODCACHE=/Users/tharnendil/Documents/go/pkg/mod GOOS=darwin GOPROXY=https://proxy.golang.org,direct GOSUMDB=sum.golang.org GOTOOLCHAIN=local GOTOOLDIR=/opt/homebrew/opt/go/libexec/pkg/tool/darwin_arm64 GOVERSION=go1.23.2 GOTELEMETRY=local GOTELEMETRYDIR=/Users/tharnendil/Library/Application Support/go/telemetry GCCGO=gccgo GOARM64=v8.0 AR=ar CC=cc CXX=c++ CGO_ENABLED=1 DB_HOST=test-hostname DB_PORT=5432] loader_test.go:62:
Error Trace: /Users/tharnendil/Repos/common/crm-v2/internal/config/loader_test.go:62
Error: Not equal:
expected: &config.Configuration{Database:struct { Host string "mapstructure:\"HOST\""; Port int "mapstructure:\"PORT\"" }{Host:"test-hostname", Port:5432}, WasInitializedWithDefaults:true}
actual : &config.Configuration{Database:struct { Host string "mapstructure:\"HOST\""; Port int "mapstructure:\"PORT\"" }{Host:"", Port:0}, WasInitializedWithDefaults:false}
Diff:
--- Expected
+++ Actual
@@ -2,6 +2,6 @@
Database: (struct { Host string "mapstructure:\"HOST\""; Port int "mapstructure:\"PORT\"" }) {
- Host: (string) (len=13) "test-hostname",
- Port: (int) 5432
+ Host: (string) "",
+ Port: (int) 0
},
- WasInitializedWithDefaults: (bool) true
+ WasInitializedWithDefaults: (bool) false
})
Test: TestLoad/initiates_config
--- FAIL: TestLoad/initiates_config (0.00s)
Expected :&config.Configuration{Database:struct { Host string "mapstructure:\"HOST\""; Port int "mapstructure:\"PORT\"" }{Host:"test-hostname", Port:5432}, WasInitializedWithDefaults:true}
Actual :&config.Configuration{Database:struct { Host string "mapstructure:\"HOST\""; Port int "mapstructure:\"PORT\"" }{Host:"", Port:0}, WasInitializedWithDefaults:false}
<Click to see difference>
=== RUN TestLoad/handles_unmarshal_error
env: [PATH=/Users/tharnendil/bin:/Users/tharnendil/Tools:/Users/tharnendil/Documents/go/bin:/Users/tharnendil/.nvm/versions/node/v22.6.0/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/tharnendil/.cache/zsh4humans/v5/fzf/bin:/Users/tharnendil/Library/Application Support/JetBrains/Toolbox/scripts:/opt/homebrew/opt/go/libexec/bin:/Users/tharnendil/Documents/go/bin MANPATH=/Users/tharnendil/.nvm/versions/node/v22.6.0/share/man:/opt/homebrew/share/man:/usr/share/man:/usr/local/share/man:/Users/tharnendil/.cache/zsh4humans/v5/fzf/man: TREE_COLORS=fi=00:mi=00:mh=00:ln=01;36:or=01;31:di=01;34:ow=01;34:st=34:tw=34:pi=01;33:so=01;33:do=01;33:bd=01;33:cd=01;33:su=01;35:sg=01;35:ca=01;35:ex=01;32 TERM=xterm-256color HOMEBREW_PREFIX=/opt/homebrew COMMAND_MODE=unix2003 SSH_AGENT_PID=81171 NVM_INC=/Users/tharnendil/.nvm/versions/node/v22.6.0/include/node LOGNAME=tharnendil HOMEBREW_REPOSITORY=/opt/homebrew XPC_SERVICE_NAME=application.com.jetbrains.goland.6031950.6031959 PWD=/Users/tharnendil/Repos/common/crm-v2/internal/config INFOPATH=/opt/homebrew/share/info: __CFBundleIdentifier=com.jetbrains.goland NVM_CD_FLAGS=-q SHELL=/bin/zsh NVM_DIR=/Users/tharnendil/.nvm PAGER=less TERMINFO=/Users/tharnendil/.terminfo LSCOLORS=ExGxDxDxCxDxDxFxFxexEx OLDPWD=/ HOMEBREW_CELLAR=/opt/homebrew/Cellar GPG_TTY=not a tty GOPATH=/Users/tharnendil/Documents/go GO15VENDOREXPERIMENT=1 USER=tharnendil GOROOT=/opt/homebrew/opt/go/libexec TMPDIR=/var/folders/h6/_h318_2j7msg73wp9q_1rqrh0000gn/T/ GO111MODULE=on SSH_AUTH_SOCK=/var/folders/h6/_h318_2j7msg73wp9q_1rqrh0000gn/T//ssh-770nQaV1bHHK/agent.81170 XPC_FLAGS=0x0 LC_ALL=en_US.UTF-8 __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0 LESS=-iRFXMx4 LS_COLORS=fi=00:mi=00:mh=00:ln=01;36:or=01;31:di=01;34:ow=04;01;34:st=34:tw=04;34:pi=01;33:so=01;33:do=01;33:bd=01;33:cd=01;33:su=01;35:sg=01;35:ca=01;35:ex=01;32 NVM_BIN=/Users/tharnendil/.nvm/versions/node/v22.6.0/bin HOME=/Users/tharnendil GOARCH=arm64 GOCACHE=/Users/tharnendil/Library/Caches/go-build GOENV=/Users/tharnendil/Library/Application Support/go/env GOHOSTARCH=arm64 GOHOSTOS=darwin GOMODCACHE=/Users/tharnendil/Documents/go/pkg/mod GOOS=darwin GOPROXY=https://proxy.golang.org,direct GOSUMDB=sum.golang.org GOTOOLCHAIN=local GOTOOLDIR=/opt/homebrew/opt/go/libexec/pkg/tool/darwin_arm64 GOVERSION=go1.23.2 GOTELEMETRY=local GOTELEMETRYDIR=/Users/tharnendil/Library/Application Support/go/telemetry GCCGO=gccgo GOARM64=v8.0 AR=ar CC=cc CXX=c++ CGO_ENABLED=1 DB_HOST=test-hostname DB_PORT=test-password WAS_INITIALIZED_WITH_DEFAULTS=foo-bar] loader_test.go:59:
Error Trace: /Users/tharnendil/Repos/common/crm-v2/internal/config/loader_test.go:59
Error: An error is expected but got nil.
Test: TestLoad/handles_unmarshal_error
--- FAIL: TestLoad/handles_unmarshal_error (0.00s)
--- FAIL: TestLoad (0.00s)
FAIL
Process finished with the exit code 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment