1

I have the following function that makes multiple calls to AWS IAM. I am able to run unit tests on single calls. However when I run a test on the one below I get a panic: "runtime error, invalid memory or nil pointer dereference"

  func (iamDependency *iamService) CreateMyUser(userName string) (string, error){

    //first IAM call
    err:=iamDependency.GetUser(&iam.GetUserInput{UserName: userName})

    if err != nil {

      fmt.Println("Failed to get user, attempting to create")
      
      //second IAM call
      err:=iamDependency.CreateUser(&iam.CreateUserInput{UserName: userName})
  
      if err != nil {
        log.Fatalf("Failed to create user\n", err )
      }
  }
}

Here is my mock and test:

type mockSomeOutput{}

type mockedIamCall{
  iamiface.IAMAPI
  Response mockSomeOutput
}

func TestCreateMyUser(t *testing.T){
  t.Run("Successful user create", fun(t *testing.T){
    mo:= mockOutput{}

    m:= mockedIamCall{Response: mo}
    
    d:= iamService{
      iamInstance: m,
    }

   mockedUser:="TestUser"
   
   _, err:= d.ResetCredentials(&mockedUser)
   
   if err != nil {
     t.Fatal("Everything should be ok")
   }
  })
}

I'm wondering whether there are any tricks or guidelines for making unit tests for this kind of function in Golang.

Appreciate any help.

2 Answers 2

1

You probably want to try using: https://github.com/golang/mock

You can creating mock implementation for the iamiface.IAMAPI (from the actual interface) then expecting the function calls and mocking the response.

Creating the mock implementation of the interface using mockgen.

mockgen -source={path to IAM API interface}

And then you can expect the function calls with something like this on the test cases:

function TestExample(t *testing.T) {
  ctrl := gomock.NewController(t)
  mockIAMAPI := mock_package.NewMockIAMAPI(ctrl)
  mockIAMAPI.EXPECT().GetUser(expectedInput).Return(mockResponse).Times(1)
}
Sign up to request clarification or add additional context in comments.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
1

@Raymond thanks for the response, it was insightful. However I seem to have found a simpler answer to my own question. I created my own interface

type UserCreator interface{
  GetUser(*iam.GetUserInput) (*iam.GetUserOutput, error)
  CreateUser(*iam.CreateUserInput) (*iam.CreateUserInput, error)
}


func CreateMyUser(iamSvc UserCreator, userName string) (string, error){

    //first IAM call
    _, err:=iamSvc.GetUser(&iam.GetUserInput{UserName: userName})

    if err != nil {

      fmt.Println("Failed to get user, attempting to create")
      
      //second IAM call
      _, err:=iamSvc.CreateUser(&iam.CreateUserInput{UserName: userName})
  
      if err != nil {
        log.Fatalf("Failed to create user\n", err )
      }
  }
}

And then for my test I just implement the interface, override these methods, and pass a mock:

type mockUserCreator{
  Response string
}

func (m * mockUserCreator) GetUser(input *iam.GetUserInput)(*iam.GetUserOutput, error){
return &iam.GetUserOutput{}, nil
}

func (m * mockUserCreator) CreateUser(input *iam.CreateUserInput)(*iam.CreateUserOutput, error){
return &iam.CreateUserOutput{}, nil
}

func TestCreateMyUser(t *testing.T){
  testcases:=[]struct{
   TestName string
  }{
    {
      TestName:"Some test"
    }
  }
  for _, tt := range testcases{
    t.Run(tt.TestName, func(t *testing.T){
      m := mockUserCreator{}

     mockUser := "TestUser"

      _, err:= CreateMyUser(&m, mockUser)
      
      if err != nil {
        t.Error("TestCreateMyUser returned and error: %s", err)
      }

    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.