作为接口访问的单例的单元测试

问题描述 投票:0回答:1

我的应用程序中有一个单例,但它不是直接作为结构发布,而是作为接口发布(因为我希望能够在初始化单例时动态选择特定的实现)。这是代码:

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(类型* defaultConfiguration)作为类型* Configuration:*配置是指向接口的指针,不是接口

而且我很困惑。为什么不能返回指向接口的指针?或者,为什么将defaultConfiguration返回为Configuration是有效的,但是将*defaultConfiguration返回为*Configuration却无效?

毕竟,对于我的用例而言,正确的单元测试是什么?

unit-testing go design-patterns singleton
1个回答
0
投票
您的代码应为:

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的指针来实现它。
© www.soinside.com 2019 - 2024. All rights reserved.