0

In golang, I often see a member function calling another member function of the same object. For example check following golang code:

type Obj struct{}

func (o Obj) First() {
    // do something
    o.Second()
}

func (o Obj) Second() {
    // do another thing
}

How would you write unit test for function First ? If you write unit test for function "First" in above code, how would you mock the function "Second" ?

To fix this, I could come up with following possibilities:

  1. Function Second() might be responsibility of another object i.e. a dependency of Obj. So Obj have more responsibilities than it should have.
  2. Pass the Object to First() as argument for a quick fix (which ends up forever in the code). Doesn't look good.
func First(o Obj) {
    // do something
    o.Second()
}

  1. Add an Interface type as argument to First() which provides behaviour Second()

But, I've ended up in a situation where I broke down First() into smaller functions for the sake of readability. The Second() simply can't be taken out to some other object.

Vikas Kaushik
  • 369
  • 2
  • 9
  • 2
    Would you mock the block of code that you abstracted into `Second` if you didn't abstract it in the first place? i.e. if you kept it inlined inside `First`? You probably wouldn't, would you? It's unreasonable to want to mock that block of code __just__ because you've now packaged it inside a separate method. Does every single method or function call need to be mocked? Did some "tool" claim it's good practice? What stops you from writing the test for `First` _without_ mocking `Second`? – mkopriva Apr 28 '23 at 14:51
  • 2
    A _unit_ is usually defined as something larger than a single method. Besides, in your tests, you should focus on behaviour, not implementation; that method `First` calls method `Second` is an implementation detail, which should have no bearing on how the test is written. – jub0bs Apr 28 '23 at 14:55
  • 1
    I tend to only mock my external dependencies – Chris Doyle Apr 28 '23 at 15:01
  • Would testing _each_ _line_ in isolation somehow "improve" the tests. – Volker Apr 28 '23 at 19:29

1 Answers1

1

Why you think you should mock Second? (sorry for starting with a question)

When you test you should focus on observable behavior (test public interface), from the test point of view it is not important what is called behind the scenes. If Second on its own does not form a dependency, does it have to be public? If it is a part of bigger feature in my opinion you should accept that, from test/user point of view it is unobservable implementation detail that you call it from First.

mleko
  • 11,650
  • 6
  • 50
  • 71