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

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


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不是?


毕竟,什么是适合我的用例的单元测试?


慕容森
浏览 163回答 1
1回答

HUX布斯

您的代码应该是:var once sync.Oncevar instance *defaultConfigurationtype 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很少需要指向接口的指针(例如)。一个接口已经是一个引用值,一个指向某种类型的指针来实现一个接口是完全没问题的。有关根本问题的更多背景信息,请阅读此答案或类似资源。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go