dpps0715 2017-04-14 09:14
浏览 40
已采纳

函数在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.

  • 写回答

1条回答 默认 最新

  • dsour68888 2017-04-14 09:32
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog