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.