Search code examples
gomockingaws-secrets-manager

Mocking a function return value called from main() in unit test


In main.go, I have some code that makes a network call to AWS Secrets manager.

func main() {
    secretName := os.Getenv("DYNAMO_SECRET")
    credentials, err := getSecret(secretName)
    if err != nil {
        logger.Errorf("Failed to retrieve secret from AWS Secrets manager %+v\n", err)
        panic(err)
    }
    router, err := setupRouter(credentials)

The getSecret(secretName) function makes a network call to AWS Secrets manager underneath the hood. In my unit test for main, I have the code below.

func TestMainProgram(t *testing.T) {
    defer mockStartServer(nil)()
    defer mockSetupRouter(mux.NewRouter(), nil)()
    main()
    t.Log("Everything is perfect.")
}

When running my unit test, I want to mock the network call to AWS Secrets Manager. Is it possible to mock the return value of getSecret(secretName)? In a Java context, I'm trying to do something similar using Mockito and the when(functionIsCalled).thenReturn(mockValue) syntax.


Solution

  • You can use a function variable to set it to some other value for testing:

    func defaultGetSecret(secretName string) (Credentials, error) {...}
    
    var getSecret=defaultGetSecret
    
    func main() {
       ...
       credentials, err:=getSecret(...)
    }
    

    In your tests, you can change getSecret to point to something else:

    func TestMain(t *testing.T) {
       getSecret=func(secretName string) (Credentials,error) {
          return mockCredentials,nil
       }
       main()
    }