Home > Blockchain >  Mocking a struct field's methods
Mocking a struct field's methods

Time:09-22

I'm working on a simple golang server app that does OAuth authentication. The server code is straight forward. For unit tests, I need to avoid making external HTTP requests to the actual OAuth provider.

So during normal Server operation, I would like to use the real calls, and when running go test, use a Mock method to prevent external HTTP requests.

I've created mocks of the OAuth methods, but I don't understand the mechanics of how to integrate them into the code. Looking through mock examples, I'm still confused about how a mock interface is used.

Here's the original code:

type Server struct {
    //This is the actual golang.org/x/oauth2 Config struct
    oauth2Config  *oauth2.Config
}


func (s *Server) handleCallback() http.HandlerFunc {
    // This is the method that makes external call. I want to mock it
    oauth2Token, err := s.oauth2Config.Exchange(s.context, r.URL.Query().Get("code"))
}

I define an interface, and the mock function

type Oauth2ConfigInterface interface {
    Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
}

type MockOauth2Config struct {
}

func (o *MockOauth2Config) Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
    return &oauth2.Token{}, nil
}

I would have thought I should change the original Server struct to use the new interface:

  • On normal Server operation, oauth2Config field is assigned with &oath2.Config{}
  • On tests, oauth2Config field is assigned with &MockOauth2Config{}
type Server struct {
    //Changed to interface
    oauth2Config  Oauth2ConfigInterface
}

...

        oauth2Config: &oauth2.Config{
            ClientID:     "",
            ClientSecret: "",
            RedirectURL:  "",
            Scopes:       []string{oidc.ScopeOpenID},
        },

But when I try to access the fields of oauth2Config, it gives me compile errors.

// compile error here
s.verifier = s.provider.Verifier(&oidc.Config{ClientID: s.oauth2Config.ClientID})

Once oauth2Config has been declared an interface, how can I access the fields?

Or am I doing this whole mock wrong?

CodePudding user response:

Answering my own question...

I may have phrased my question badly but I do think people in the future will run into the same question.

@bcmills gave the best solution: How to mock net.Interface

It is far more elegant than mocking using interface. Especially for a case like this where third-party func/methods are involved.

  • Related