Closed MrBear2018 closed 2 years ago
做了如下修改, 就正确了
type Singleton struct {
tmp int
}
func TestGetInstance(t *testing.T) {
Convey("grpc server test", t, func() {
a := GetInstance()
b := GetInstance()
assert.Equal(t, true, a==b)
})
}
注意, 这里的assert.Equal 也许要改一下形式, 用==来直接判定地址是否一样, 因为 assert.Equal 函数并不是比较引用(内存地址), 而是比较引用的值
单例本身是没问题的哈,这个是一个很简单的示例,每次获取的也只是同一个地址而已
就你的这个示例而言,只要里面加点字段就不会有你上面例子的这个问题了
单例本身没有问题,但是你代码中 singleton 的申明是需要加上字段的;另外 assert.Equal 直接调用也是有问题的,不会判断地址值而是判断的对象值。参考:https://github.com/stretchr/testify/issues/1076 所以你的 singleton_test 并没有达到实际的测试效果,只是“负负得正”而已。一个正确的单测:
func TestGetInstance(t *testing.T) {
s1 := GetInstance()
s2 := GetInstance()
s3 := GetLazyInstance()
s4 := GetLazyInstance()
assert.Equal(t, reflect.ValueOf(s1).Pointer(), reflect.ValueOf(s2).Pointer())
assert.Equal(t, reflect.ValueOf(s3).Pointer(), reflect.ValueOf(s4).Pointer())
assert.NotEqual(t, reflect.ValueOf(s2).Pointer(), reflect.ValueOf(s3).Pointer())
}
单例本身没有问题,但是你代码中 singleton 的申明是需要加上字段的;另外 assert.Equal 直接调用也是有问题的,不会判断地址值而是判断的对象值。参考:stretchr/testify#1076 所以你的 singleton_test 并没有达到实际的测试效果,只是“负负得正”而已。一个正确的单测:
func TestGetInstance(t *testing.T) { s1 := GetInstance() s2 := GetInstance() s3 := GetLazyInstance() s4 := GetLazyInstance() assert.Equal(t, reflect.ValueOf(s1).Pointer(), reflect.ValueOf(s2).Pointer()) assert.Equal(t, reflect.ValueOf(s3).Pointer(), reflect.ValueOf(s4).Pointer()) assert.NotEqual(t, reflect.ValueOf(s2).Pointer(), reflect.ValueOf(s3).Pointer()) }
的确是的哈
我测试的时候, 发现示例单例模式有问题
singleton.go
singleton_test.go
预期应该是不可以通过, 因为返回的是两个实例; 但是测试发现, 这样是能通过的,
错误的原因在于, singleton结构体是一个空结构体, 对于空结构体, go有特殊实现, 每次返回的地址都是全局变量 zerobase 的地址;
参考文档:https://segmentfault.com/a/1190000039315999