У меня есть одноэлементное приложение в моем приложении, но оно публикуется не как непосредственно структура, а как интерфейс (потому что я хочу иметь возможность динамически выбирать конкретную реализацию при инициализации одноэлементного режима). Вот код:
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 в возвращаемом аргументе : * Конфигурация указатель на интерфейс, а не интерфейс
И я очень запутался. Почему я не могу вернуть указатель на интерфейс? Или почему возврат defaultConfiguration
как Configuration
допустим, а возврат *defaultConfiguration
как *Configuration
- нет?
И, в конце концов, каков надлежащий юнит-тест для моего варианта использования?