Home > front end >  Calling an interface method that calls another method on the same interface
Calling an interface method that calls another method on the same interface

Time:12-22

Say I have the following interface in golang

type InterfaceA interface {
   Method1()
   Method2()
}

func (o *Obj) Method1() {
  o.Method2()
}

func (o *Obj) Method2() {
}

obj1 := //instantiate a type that implements the above interface

If I am writing unit tests for Method1, how can I create a mock object for Obj while at the same execute code in Method1 on a real Obj object? The challenge is that Obj calls Method2 which has to be on the mocked object while Method1 needs to be called on the real object.

CodePudding user response:

I am not sure, if I understand why you want to do this exactly. But You could add the "real" object as a field of the mock object and call its method.

// the mock object has a field of type Obj
type MockObject struct {
    obj Obj
}

// then it can call the "real" objects method
func (o *MockObject) Method1() {
  o.obj.Method2()
}

func (o *MockObject) Method2() {
}

I am doing something like this sometimes to implement an interface. For example, like below. This way I can use the server type and stick it into ListenAndServe since it implements ServeHTTP.

type Server struct {
    router  *http.ServeMux
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    s.router.ServeHTTP(w, r)
}

func NewServer() *Server {
    return &Server{
        router: http.NewServeMux(),
    }
}

s := server.NewServer()
http.ListenAndServe(":8080", s)

CodePudding user response:

Go doesn't really have dynamic dispatch. The type of Method1() receiver o is *Obj so the expression o.Method2() will always call Obj.Method2(), the interface is not involved here at all.

So what you want is impossible. But that shouldn't be an issue as we normally unit-test at object level, not method level.

  • Related