Search code examples
unit-testinggointerfaceoverriding

How to Mock only specific method in Golang


I am fairly new to golang and I am struggling with a simple task.

I have the following class in golang

type struct A {
}

func (s *A) GetFirst() {
    s.getSecond()
}

func (s *A) getSecond() {
    // do something
}

And I want to write some tests for it however for that I need to override getSecond(). I attempted to do the following in my test files

type Ai interface {
    getSecond()
}

type testA struct {
    A
}

func (s *testA) getSecond() {
     // do nothing
}

func TestA(t *testing.T) {
   a := &A{}
   t := &testA{A: a}
   t.GetFirst()  
}

The idea here is to expose A getSecond() method to an interface and override by using embedding however this does not seem to work. The test still calls the original implementation of getSecond() instead of my mocked one.

One solution would of course be to create a proper interface for A which contains getFirst() and getSecond() and then in the test create a struct implementing both where getFirst() call the original implementation and getSecond() a dummy however I feel this is cumbersome and not the correct way of doing things.

Another possibility would be to assign getSecond() in the real implementation to a variable and override the variable in test but I also feel it is a bit strange to do this just for a simple override.

Am I going all wrong about this? Is there any way simpler way to do this using golang?


Solution

  • You can't really override methods in golang as per this answer. However, as you point out you can have a separate interface for the "getSecond method" and have one implementation in your test cases and one implementation in your actual code.

    type s interface{ 
        getSecond()
    }
    
    type A struct{
        s
    }
    
    type a struct{
    
    }
    
    func (s *A) GetFirst() {
        s.getSecond()
    }
    
    func (s a) getSecond() {
        // do something
    }
    
    //Use a 
    A{a{}}
    

    Then in Test have a different implementation of 'a'

    type ta struct {
    
    }
    func (s ta) getSecond() {
        // do nothing
    }
    
    A{ta{}}