I have a singleton in my application, but it's published not as a struct directly, but as an interface (because I want to be able to dynamically select the particular implementation upon singleton initialization). Here's the code:
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
}
Then I decided to write a unit-test that would check that NewConfiguration()
will actually return the same instance each time:
func TestNewConfigurationSameInstance(t *testing.T) {
configuration1 := NewConfiguration()
configuration2 := NewConfiguration()
if &configuration1 != &configuration2 {
t.Error()
}
}
I thought it would make sense to compare the addresses of the returned instances, however, this test fails.
Then I thought, well, maybe I have to return a pointer to an instance, so I've changed the code to look like this:
func NewConfiguration() *Configuration {
once.Do(func() {
instance = defaultConfiguration{}
})
return &instance
}
But this doesn't even compile: it fails with the error message
cannot use &instance (type *defaultConfiguration) as type *Configuration in return argument: *Configuration is pointer to interface, not interface`
And I've got very confused. Why can't I return a pointer to an interface? Or, why returning defaultConfiguration
as Configuration
is valid, but returning *defaultConfiguration
as *Configuration
is not?
And, after all, what is the proper unit-test for my use-case?
Aucun commentaire:
Enregistrer un commentaire