作为接口访问的单例的单元测试
Unit test of a singleton accessed as an interface
我的应用程序中有一个单例,但它不是直接作为结构发布,而是作为接口发布(因为我希望能够在单例初始化时动态 select 特定实现)。这是代码:
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()
每次实际上 return 相同的实例:
func TestNewConfigurationSameInstance(t *testing.T) {
configuration1 := NewConfiguration()
configuration2 := NewConfiguration()
if &configuration1 != &configuration2 {
t.Error()
}
}
我认为比较 returned 实例的地址是有意义的,但是,这个测试失败了。
然后我想,好吧,也许我必须 return 一个指向实例的指针,所以我将代码更改为如下所示:
func NewConfiguration() *Configuration {
once.Do(func() {
instance = defaultConfiguration{}
})
return &instance
}
但这甚至无法编译:它失败并显示错误消息
cannot use &instance (type *defaultConfiguration) as type *Configuration in return argument:
*Configuration is pointer to interface, not interface
我很困惑。为什么我不能 return 指向接口的指针?或者,为什么 returning defaultConfiguration
as Configuration
有效,但 returning *defaultConfiguration
as *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
)。接口已经是一个引用值,用指向某种类型的指针来实现接口是完全没问题的。
有关根本问题的更多背景信息 或类似资源。
我的应用程序中有一个单例,但它不是直接作为结构发布,而是作为接口发布(因为我希望能够在单例初始化时动态 select 特定实现)。这是代码:
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()
每次实际上 return 相同的实例:
func TestNewConfigurationSameInstance(t *testing.T) {
configuration1 := NewConfiguration()
configuration2 := NewConfiguration()
if &configuration1 != &configuration2 {
t.Error()
}
}
我认为比较 returned 实例的地址是有意义的,但是,这个测试失败了。
然后我想,好吧,也许我必须 return 一个指向实例的指针,所以我将代码更改为如下所示:
func NewConfiguration() *Configuration {
once.Do(func() {
instance = defaultConfiguration{}
})
return &instance
}
但这甚至无法编译:它失败并显示错误消息
cannot use &instance (type *defaultConfiguration) as type *Configuration in return argument: *Configuration is pointer to interface, not interface
我很困惑。为什么我不能 return 指向接口的指针?或者,为什么 returning defaultConfiguration
as Configuration
有效,但 returning *defaultConfiguration
as *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
)。接口已经是一个引用值,用指向某种类型的指针来实现接口是完全没问题的。
有关根本问题的更多背景信息