dph58509 2017-12-21 07:14
浏览 47
已采纳

Go测试包中的模拟statsd客户端

I use this statsd package to send metrics to our statsd server. To initialize the client, I call a metrics.Setup() in my main which does the init. This package looks like this:

package:

package metrics

import (
    "fmt"

    "github.com/cactus/go-statsd-client/statsd"
)

// Client can be used to send stats to
var Client StatsdAccess

// Setup initialises metrics gathering
func Setup() {
    if Client == nil {
        prefix := fmt.Sprintf("app.%s", logging.GetHost())
        std, err := statsd.NewBufferedClient(fmt.Sprintf("localhost:1234", prefix, 0, 0)
        if err != nil {
            logrus.Errorf("unable to dial the statsd host: %q", err)
            return
        }
        Client = std
    }
}

// StatsdAccess is used as interface to statsd functions
type StatsdAccess interface {
    Inc(stat string, value int64, rate float32) error
    Gauge(stat string, value int64, rate float32) error
    Timing(stat string, delta int64, rate float32) error
}

From this moment on, the other package send metrics though this global Client by doing this: metrics.Client.Inc("some.counter", 1, 1.0). This works fine, but now I have a problem with my test files. They now fail when a package actually uses the metrics package to send metrics. This is obvious, because the metrics package has not been initialized, etc. So my question -I think- is: how can I mock the statsd client in my test files?

  • 写回答

1条回答 默认 最新

  • donglv9116 2017-12-21 17:45
    关注

    Many of the project I work on use statsd and have teetered between just leaving the calls in the tests, because they are so lightweight, and programming to a metrics interface (as you have already done StasdAccess).

    Since the interface is already initialized, you should be able to use the interface to break the configuration dependency in your code, and provide a test implementation to use in your tests:

    package_metrics/
       testing.go
    

    // testing.go
    
    type StubStatsd struct {}
    func (s StubStatsd) Inc(stat string, value int64, rate float32) error {
      return nil
    }
    func (s StubStatsd) Gauge(...
    func (s StubStatsd) Timing(...
    

    Now when your tests would like to call a method or initialize a component that requires a StatsdAccess parameter it could use the testing stub to meet the requirements

    func TestSomething_NeedsStatsd(t *testing.T) {
         statsdStub := StubStatsd{}
         someMethodThatRequiresStatsd(stasdStub)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器