代理模式,单元测试用例真的写得详细,
受教~
proxy.go
package proxy import ( //"errors" "fmt" ) type UserFinder interface { FindUser(id int32) (User, error) } type User struct { ID int32 } type UserList []User func (t *UserList) FindUser(id int32) (User, error) { for i := 0; i < len(*t); i++ { if (*t)[i].ID == id { return (*t)[i], nil } } return User{}, fmt.Errorf("User %d could not be found\n", id) } type UserListProxy struct { SomeDatabase UserList StackCache UserList StackCapacity int DidLastSearchUsedCache bool } func (u *UserListProxy) FindUser(id int32) (User, error) { user, err := u.StackCache.FindUser(id) if err == nil { fmt.Println("Returning user from cache") u.DidLastSearchUsedCache = true return user, nil } else { user, err = u.SomeDatabase.FindUser(id) if err != nil { return User{}, err } fmt.Println("Returning from database") u.addUserToStack(user) u.DidLastSearchUsedCache = false return user, nil } } func (t *UserList) addUser(newUser User) { *t = append(*t, newUser) } func (u *UserListProxy) addUserToStack(user User) { if len(u.StackCache) >= u.StackCapacity { u.StackCache = append(u.StackCache[1:], user) } else { u.StackCache.addUser(user) } }
proxy_test.go
package proxy import ( "fmt" "math/rand" "testing" ) func Test_UserListProxy(t *testing.T) { someDatabase := UserList{} rand.Seed(2342342) for i := 0; i < 1000; i++ { n := rand.Int31() fmt.Println(n) someDatabase = append(someDatabase, User{ID: n}) } proxy := UserListProxy{ SomeDatabase: someDatabase, StackCapacity: 2, StackCache: UserList{}, } knowsIDs := [3]int32{ someDatabase[3].ID, someDatabase[4].ID, someDatabase[5].ID} t.Run("FindUser - Empty cache", func(t *testing.T) { user, err := proxy.FindUser(knowsIDs[0]) if err != nil { t.Fatal(err) } if user.ID != knowsIDs[0] { t.Error("Returned user name doesn't match with expected") } if len(proxy.StackCache) != 1 { t.Error("After one successful search in an empty cache, the size of it must be one") } if proxy.DidLastSearchUsedCache { t.Error("No user can be returned from an empty cache") } }) t.Run("FindUser - One user, ask for the same user", func(t *testing.T) { user, err := proxy.FindUser(knowsIDs[0]) if err != nil { t.Fatal(err) } if user.ID != knowsIDs[0] { t.Error("Returned user name doesn't match with expected") } if len(proxy.StackCache) != 1 { t.Error("Cache must not grow if we asked for an object that stored on it") } if !proxy.DidLastSearchUsedCache { t.Error("The user should have been returned from the cache") } }) user1, err := proxy.FindUser(knowsIDs[0]) if err != nil { t.Fatal(err) } user2, _ := proxy.FindUser(knowsIDs[1]) if proxy.DidLastSearchUsedCache { t.Error("The user wasn't stored on the proxy cache yet") } user3, _ := proxy.FindUser(knowsIDs[2]) if proxy.DidLastSearchUsedCache { t.Error("The user wasn't stored on the proxy cache yet") } for i := 0; i < len(proxy.StackCache); i++ { if proxy.StackCache[i].ID == user1.ID { t.Error("User that should be gone was found") } } if len(proxy.StackCache) != 2 { t.Error("After inserting 3 users the cache should no grow" + " more than to two") } for _, v := range proxy.StackCache { if v != user2 && v != user3 { t.Error("A non expected user was found on the cache") } } }