Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 354
Alexandre Thenorio Avatar asked Mar 16 '17 16:03

Alexandre Thenorio


People also ask

What is stub in Golang?

stub is replacement for some dependency in your code that will be used during test execution. It is typically built for one particular test and unlikely can be reused for another because it has hardcoded expectations and assumptions. mock takes stubs to next level.

What is mock Golang?

The mockgen command is used to generate source code for a mock class given a Go source file containing interfaces to be mocked. It supports the following flags: -source : A file containing interfaces to be mocked. -destination : A file to which to write the resulting source code.

What is mocking in Golang?

Mocking in golang is done with the help of interfaces. Mocking in unit testing is important as it ensure that variables, methods and functions modified outside the scope of the function being tested do not affect the test output. Here is the implementation of mocking.go

How to override methods in test cases in Golang?

It would be nice to be able to catch such scenario with a test 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.

What is the difference between Python and Golang?

Languages like Python provide standardised libraries and frameworks that make it easy to mock methods and functions inside an impure function or method. With python unit tests are pretty easy thus achieving a 100% test coverage is the norm. Go or Golang is a light weight language that is not C based.

Is Golang easy to learn?

Go or Golang is a light weight language that is not C based. Its syntax is pretty easy, I like to refer to golang as a " Pythonized version of Java " due to the similarity of concepts imported from both Java and Python. Golang does not have an official package that supports mocking of methods during unit testing.


1 Answers

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{}}
like image 181
Benjamin Kadish Avatar answered Oct 17 '22 09:10

Benjamin Kadish