函数在golang中通过接口模拟

I am trying to write a unit test code form following code which has 3 level of function calling as below:

The main function calls function A() and then function A calls function B() and C() depending upon some condition and function B calls function E() and F(), whereas function C calls function G() and H() on some condition.
The above like the code I have developed, Here I want to mock function E() and F() for function B, and G() and H() for function C. Please suggest me how to do it using interface.

Abstract function type

You can do it with dependency injection not using interfaces:

import (
    "fmt"
    "math"
)

type a func(float64) float64

func A(arg float64) float64 {
    return math.Pow(arg, 2)
}

func mock(arg float64) float64 {
    return math.Sqrt(arg)
}

func b(function a, arg float64) float64 {
    return function(arg)
}

func main() {
    fmt.Println(b(A, 2))
    fmt.Println(b(mock, 2))
}

Function is first class citizen in Go

In programming language design, a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities.

It means you can pass function as argument among other possibilities. And of course you can declare an abstract type based on function with concrete interface (Don't confuse with interface type)

Interface approach

You can make compositions using your functions

import (
    "fmt"
    "math"
)

// Declare an interface type with dependencies
type HGer interface {
    H(float64) float64
    G(float64) float64
}

// Declare a dependent type with embedded interface
type Dependent struct {
    HGer
}

func (d *Dependent) B(arg float64) float64 {
    return d.H(arg) * d.G(arg)
}

// Implement the interface for an actual program
type ImplHGer struct{}

func (i *ImplHGer) H(arg float64) float64 {
    return math.Pow(arg, 2)
}

func (i *ImplHGer) G(arg float64) float64 {
    return math.Sqrt(arg)
}

// Implement the interface for mock of dependencies
type MockHGer struct{}

func (i *MockHGer) H(arg float64) float64 {
    return float64(0)
}

func (i *MockHGer) G(arg float64) float64 {
    return float64(0)
}

func main() {
    // Use real implementation
    a := Dependent{new(ImplHGer)}
    // Use the mock
    b := Dependent{new(MockHGer)}
    fmt.Println(a.B(8)) // 181.01933598375618
    fmt.Println(b.B(8)) // 0
}

Embedding

Including an anonymous field in a struct is known as embedding. In this case the Discount type is embedded in the PremiumDiscount type. All the methods of Discount are instantly available on the PremiumDiscount type. Furthermore those same methods can be hidden

It is possible to embed interface to struct to extend it's behavior or to be more specific - declare abstract dependency.