<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] # Mock依賴 有的時候,由于業務邏輯的復雜性,功能代碼并不會就這么直接,往往還會摻雜很多其他組件,這就給我們的測試工作帶來很大的麻煩,我這里列舉幾個常見的依賴: * 組件依賴 * 函數依賴 組件依賴和函數依賴是兩種比較常見的依賴,但是,這兩種依賴也是可以擴展開來說的,既可能來自于我們自己編寫的組件/函數,也可能是引入其他人寫的。但是,無妨,對于這些情況,我們都會做一些分析 ## 組件依賴處理 傳一個 Stub 組件進入,從而達到控制依賴組件行為的效果 舉一個例子先,例如我們比較常見的 Service 層和 DAO 層的操作,Service 處理完邏輯之后,交給 DAO 層進行持久化,或者需要調用 DAO 層從持久化中獲取一些必要的數據;在測試的時候,我們很多時候不希望真的持久化或者從持久化中獲取數據,那么就會對 DAO 層進行一些 Mock ~~~ import "fmt" type Data struct { Field string } type Dao interface { ReadAll() []Data SaveData(d *Data) } type MongoDao struct { } func (d MongoDao) ReadAll() []Data { return []Data{} } func (d MongoDao) SaveData(data *Data) { //... } type Service struct { Dao *Dao } func (s *Service) Login (username string) bool { users := (*s.Dao).ReadAll() for _, user := range users { if username == user.Field { return true } } return false } func Newservice(d Dao) *Service { srv := Service{Dao: &d} return &srv } func main() { d := MongoDao{} srv := Newservice(d) fmt.Println(srv.Login("abc")) } ~~~ 這里我們想要測試**Service**的正確性,但是又不想要真的持久化 DAO,所以,這個時候我們會自己創建一個 Stub,然后提供給 Service,同時,我們還能操作 DAO 的行為,達到運行得效果 ~~~ //用StubDao代替Mongodb type StubDao struct { } func (d StubDao) ReadAll() []Data { return []Data{Data{"abc"}} } func (d StubDao) SaveData(data *Data) { } func TestLogin(t *testing.T) { d := StubDao{} srv := NewService(d) rst := srv.Login("abc") if !rst { t.Error("login error") } } ~~~ 這里對測試代碼稍微改了一下,可以發現,我們可以通過修改一個變量來控制 Stub 的輸出,從而達到測試不同功能的效果,這就解決了組件依賴的問題 ## 函數依賴 函數依賴相比于組件依賴會更麻煩一點,因為我們在前面可以看到,組件依賴的話我們可以傳遞 Stub 進行,這樣我們可以隨意得控制 Stub 的行為,但是函數不行呀,這里我們又不能傳函數進去,因為函數是被 import 進去的啊。問題就在這了,因為函數是被 import 進去的,所以可以理解為函數是全局的了,既然這樣,那么我們為什么不修改一下函數呢?什么意思?我們先來看著正常的業務例子 ~~~ var Login = func(username, password string) bool { if username == password { return false } return true } func Reply(username, password, msg string) bool { if Login(username, password) { fmt.Println(msg) return true } return false } func stu() { Reply("a", "b", "aa") Reply("a", "b", "bb") } ~~~ 要先登錄,然后登錄完之后我們才能回復消息,這里我們的登錄邏輯是簡單的,但是,在實際業務中可能這里的登錄邏輯就設計到 DB 訪問等等,我們希望不走真實的邏輯,而是自己來控制`Login`的行為 先分析一下我們的 UT 目的,我們的目的是測試`Reply`函數,我們期望是`Login`成功,那么`Reply`也應該是成功的;如果`Login`失敗,那么`Reply`也應該是失敗的。這個測試結論不應該被`Login`所影響,及時以后`Login`邏輯修改了,我們也應該是這個邏輯,不會受到影響,那么我們可以這么編寫 UT ~~~ func TestSuccReply(t *testing.T) { origLogin := Login defer func() { Login = origLogin }() Login = func(username, password string) bool { return true } if !Reply("a", "a", "aaa") { t.Errorf("reply false for login success") } } func TestLogin(t *testing.T) { origLogin := Login defer func() { Login = origLogin }() Login = func(username, password string) bool { return false } if Reply("a", "a", "aa") { t.Errorf("reply true for login fail") } } ~~~ 這里可以發現,我們是修改了`Login`這個函數的代碼,從而控制`Login`函數的返回值,這樣我們就可以測試我們寫的代碼的邏輯是否正確了
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看