unit-testing - 作为接口访问的单例的单元测试
问题描述
我的应用程序中有一个单例,但它不是直接作为结构发布,而是作为接口发布(因为我希望能够在单例初始化时动态选择特定的实现)。这是代码:
var once sync.Once
var instance defaultConfiguration
type Configuration interface {
GetFoo() string
}
type defaultConfiguration struct {
}
func (dc defaultConfiguration) GetFoo() string {
return "foo"
}
func NewConfiguration() Configuration {
once.Do(func() {
instance = defaultConfiguration{}
})
return instance
}
然后我决定编写一个单元测试来检查NewConfiguration()
每次是否实际返回相同的实例:
func TestNewConfigurationSameInstance(t *testing.T) {
configuration1 := NewConfiguration()
configuration2 := NewConfiguration()
if &configuration1 != &configuration2 {
t.Error()
}
}
我认为比较返回实例的地址是有意义的,但是,这个测试失败了。
然后我想,好吧,也许我必须返回一个指向实例的指针,所以我将代码更改为如下所示:
func NewConfiguration() *Configuration {
once.Do(func() {
instance = defaultConfiguration{}
})
return &instance
}
但这甚至无法编译:它失败并显示错误消息
不能使用 &instance (type *defaultConfiguration) 作为类型 *Configuration 在返回参数中: *Configuration 是指向接口的指针,而不是接口
我很困惑。为什么我不能返回指向接口的指针?或者,为什么按原样返回defaultConfiguration
是Configuration
有效的,但*defaultConfiguration
按原样返回*Configuration
不是?
毕竟,什么是适合我的用例的单元测试?
解决方案
您的代码应该是:
var once sync.Once
var instance *defaultConfiguration
type Configuration interface {
GetFoo() string
}
type defaultConfiguration struct {
}
func (dc *defaultConfiguration) GetFoo() string {
return "foo"
}
func NewConfiguration() Configuration {
once.Do(func() {
instance = &defaultConfiguration{}
})
return instance
}
因为Configuration
是一个接口,你想要一个指针defaultConfiguration
来实现它。
*Configuration
很少需要指向接口的指针(例如)。一个接口已经是一个引用值,一个指向某种类型的指针来实现一个接口是完全没问题的。
有关根本问题的更多背景信息,请阅读此答案或类似资源。
推荐阅读
- r - 如何在字符串中转换数据框以修复错误以正确绘制某些图形?
- python - 组合矩阵时如何保留索引?
- excel - VBA 宏无法准确地将 VLOOKUP 插入 Excel 单元格
- rust - 具有未实现 Copy 特征的输入的基准函数
- python - Pyspark:将列从字符串数字转换为时间戳类型
- excel - 从错误的单元格开始访问 VBA 导出到 Excel
- java - liquibase-maven-plugin 与 testcontainers 的使用
- python - 无法使用 Python 将文件上传到 Azure Notebooks 中 Azure Datalake Gen 2 中容器中的目录
- windows - Postgresql:端口 5432 上的连接被拒绝
- kubernetes - Kubernetes 没有为入口分配地址