Go interfaces usually work best when consumers define only the behavior they need.

interfaces Small consumer-owned interfaces keep packages decoupled and tests simple.

Small Interfaces

methodCount
small_interfaces.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

func main() {
	var methodCount = 1
	interfaceName := "Reader"
	if methodCount > 1 {
		interfaceName = "Repository"
	}

	focused := methodCount <= 2
	testDouble := "simple fake"
	if !focused {
		testDouble = "large mock"
	}

	fmt.Println("interface=", interfaceName)
	fmt.Println("methods=", methodCount)
	fmt.Println("focused=", focused)
	fmt.Println("test_double=", testDouble)
}
package main

import "fmt"

func main() {
	var methodCount = 2
	interfaceName := "Reader"
	if methodCount > 1 {
		interfaceName = "Repository"
	}

	focused := methodCount <= 2
	testDouble := "simple fake"
	if !focused {
		testDouble = "large mock"
	}

	fmt.Println("interface=", interfaceName)
	fmt.Println("methods=", methodCount)
	fmt.Println("focused=", focused)
	fmt.Println("test_double=", testDouble)
}
package main

import "fmt"

func main() {
	var methodCount = 5
	interfaceName := "Reader"
	if methodCount > 1 {
		interfaceName = "Repository"
	}

	focused := methodCount <= 2
	testDouble := "simple fake"
	if !focused {
		testDouble = "large mock"
	}

	fmt.Println("interface=", interfaceName)
	fmt.Println("methods=", methodCount)
	fmt.Println("focused=", focused)
	fmt.Println("test_double=", testDouble)
}
  1. methodCount ← 1, interfaceName ← "Reader", focused ← true, testDouble ← "simple fake"

    5func main() {6  var methodCount→ 1 = 1 //@methodCount=2, 57  interfaceName→ "Reader" := "Reader"8  if methodCount > 1 {9    interfaceName = "Repository"10  }1112  focused→ true := methodCount1 <= 213  testDouble→ "simple fake" := "simple fake"14  if !focused {15    testDouble = "large mock"16  }1718  fmt.Println("interface=", interfaceName"Reader")19  fmt.Println("methods=", methodCount1)20  fmt.Println("focused=", focusedtrue)21  fmt.Println("test_double=", testDouble"simple fake")22}
    outputinterface= Reader
    methods= 1
    focused= true
    test_double= simple fake
  1. methodCount ← 2, interfaceName ← "Reader"

    5func main() {6  var methodCount→ 2 = 27  interfaceName→ "Reader" := "Reader"8  if methodCount > 1 {
  2. interfaceName ← "Repository"

    7interfaceName := "Reader"8if methodCount2 > 1 {9  interfaceName→ "Repository" = "Repository"10}
  3. focused ← true, testDouble ← "simple fake"

    12  focused→ true := methodCount2 <= 213  testDouble→ "simple fake" := "simple fake"14  if !focused {15    testDouble = "large mock"16  }1718  fmt.Println("interface=", interfaceName"Repository")19  fmt.Println("methods=", methodCount2)20  fmt.Println("focused=", focusedtrue)21  fmt.Println("test_double=", testDouble"simple fake")22}
    outputinterface= Repository
    methods= 2
    focused= true
    test_double= simple fake
  1. methodCount ← 5, interfaceName ← "Reader"

    5func main() {6  var methodCount→ 5 = 57  interfaceName→ "Reader" := "Reader"8  if methodCount > 1 {
  2. interfaceName ← "Repository"

    7interfaceName := "Reader"8if methodCount5 > 1 {9  interfaceName→ "Repository" = "Repository"10}
  3. focused ← false, testDouble ← "simple fake"

    12focused→ false := methodCount5 <= 213testDouble→ "simple fake" := "simple fake"14if !focused {
  4. testDouble ← "large mock"

    13testDouble := "simple fake"14if !focusedfalse {15  testDouble→ "large mock" = "large mock"16}
  5. fmt.Println("interface=", interfaceName)

    18  fmt.Println("interface=", interfaceName"Repository")19  fmt.Println("methods=", methodCount5)20  fmt.Println("focused=", focusedfalse)21  fmt.Println("test_double=", testDouble"large mock")22}
    outputinterface= Repository
    methods= 5
    focused= false
    test_double= large mock