如何正确地模拟导入的库?

huangapple go评论90阅读模式
英文:

How to properly mock an imported library?

问题

我有一个导入语句:

import {
    "github.com/aws/aws-sdk-go/service/route53"
}

然后我使用它来处理 AWS Route 53 中的主机区域。我看到我创建的代码在当前设置下正常工作。

为了简化开发过程,我想在开发过程中创建一个我使用的库方法的模拟。

我在配置中有一个键,像这样 env="development"env="production"

我的计划是在开发环境下,如果环境是开发环境,我将添加一个名为 route53 的自定义对象,并导入它。

如何更好地实现这个目标?
Go语言是否支持条件导入,像这样:

if (env=="development") {
    import "./route53-mock"
} else {
    "github.com/aws/aws-sdk-go/service/route53"
}
英文:

I have an import:

import {
    "github.com/aws/aws-sdk-go/service/route53"
}

Which I then use to work with host zones in AWS Route 53.
I see that the code I created works properly now with the current setup.

To simplify development process, I want to create a mock of the library methods I use while developing.

I have a key in config, like this env="development" or env="production".

My plan is to add my own object that is route53 with the needed methods and import it if the env is development.

How do I do it better?
Does golang support conditional importing, like this:

if (env=="development") {
    import "./route53-mock"
} else {
    "github.com/aws/aws-sdk-go/service/route53"
}

答案1

得分: 2

Go不支持条件导入,至少在当前稳定版本中不支持。

使用包含所需方法的接口是解决这个问题的好方法:

type TrafficPolicyLister interface {
   ListTrafficPolicies(*route53.ListTrafficPoliciesInput) (*route53.ListTrafficPoliciesOutput, error)
}

现在,您可以在以前使用route53.Route53的任何地方使用该接口。在生产中,您将传递一个类型为route53.Route53的对象(实现该接口),但在开发过程中,您可以传递一个模拟对象:

type TrafficPolicyListerMock struct {}

func (t *TrafficPolicyListerMock) ListTrafficPolicies(input *route53.ListTrafficPoliciesInput) (*route53.ListTrafficPoliciesOutput, error) {
    // 返回您希望模拟对象返回的内容
}
英文:

Go does not support conditional importing–at least not in the current stable version.

An interface with the methods you need to use is a good fit to solve this problem:

type TrafficPolicyLister interface {
   ListTrafficPolicies(*route53.ListTrafficPoliciesInput) (*route53.ListTrafficPoliciesOutput, error)
}

Now you can use the interface wherever you would previously use route53.Route53. In production you would pass an object of type route53.Route53 (which implements that interface) but during development you can pass a mock:

type TrafficPolicyListerMock struct {}

func (t *TrafficPolicyListerMock) ListTrafficPolicies(input *route53.ListTrafficPoliciesInput) (*route53.ListTrafficPoliciesOutput, error) {
    // return whatever you want your mock to return
}

答案2

得分: 1

如果你想进行单元测试,请阅读 @csm 的回答。

如果你想要一个开发环境(不是单元测试),你可能应该看看 minio,它是一个自托管的 S3 实现。你可以使用环境变量来注入 S3 的端点。然后你可以自由地在开发中使用自己的 minio 服务器。

英文:

If you want to do unit testing, read the answer of @csm.

If you want to have a development environment (not unit testing), you should probably look at minio, effectively a self-hosted S3 implementation. You should use environment variable to inject the S3 endpoints. Then you're free to use your own minio server for your development.

答案3

得分: -1

"golang是否支持条件导入?" 答案:不支持。请查看语言规范。

"我该如何做得更好?" 答案:通过自己的包将调用路由到route53,根据你的环境/构建标签/命令行参数等,在模拟和真实的route53之间进行切换。

英文:

"Does golang support conditional importing [?]". Answer: No. Just take a look at the language spec.

"How do I do it better?" Answer: Route calls to route53 through your own package which switches between mock and real route53 depending on your environment/build -tags/cmdlineargs/whatever.

huangapple
  • 本文由 发表于 2017年2月15日 15:06:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/42242713.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定