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.

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

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度