2014-10-27 78 views
0

所以我想在測試中將控制器與模型隔離開來,以便在出現問題時能夠輕鬆找出問題。之前,我只是用模擬數據命中端點,但難以排除故障,因爲測試從路由器一直運行到數據存儲。所以我想也許我會爲每個控制器(和模型)創建兩個版本(MockController vs Controller),並根據模式變量的值使用一個版本。簡而言之,這是我計劃實施它的方式。如何在測試中將模型與控制器分開?

const mode string = "test" 

// UserModelInterface is the Interface for UserModel 
type UserModelInterface interface { 
    Get() 
} 

// UserControllerInterface is the Interface for UserController 
type UserControllerInterface interface { 
    Login() 
} 

// NewUserModel returns a new instance of user model 
func NewUserModel() UserModelInterface { 
    if mode == "test" { 
     return &MockUserModel{} 
    } else { 
     return &UserModel{} 
    } 
} 

// NewUserController returns a new instance of user controller 
func NewUserController(um UserModelInterface) UserControllerInterface { 
    if mode == "test" { 
     return &MockUserController{} 
    } else { 
     return &UserController{} 
    } 
} 

type (
    UserController struct {um UserModelInterface} 
    UserModel struct {} 

    // Mocks 
    MockUserController struct {um UserModelInterface} 
    MockUserModel struct {} 
) 

func (uc *UserController) Login() {} 
func (um *UserModel) Get() {} 

func (uc *MockUserController) Login() {} 
func (um *MockUserModel) Get() {} 

func main() { 
    um := NewUserModel() 
    uc := NewUserController(um) 
} 

這樣我可以只跳過了MockUserController.Login() SQL查詢,只驗證有效載荷,並返回一個有效的響應。

您對這種設計有什麼看法?你有更好的實施?

+0

爲什麼不使用建立標籤做你需要什麼? – Peter 2014-10-27 04:35:39

回答

0

我會讓調用NewUserController()和NewUserModel()的代碼決定是創建一個模擬還是真實的實現。如果您一直使用這種依賴注入模式,則代碼將變得更清晰,耦合也更少。例如。如果用戶控制器由服務器使用,它看起來像沿着線:

真:

U:= NewUserController() S:= NEWSERVER(U)

在測試中:

U:= NewMockUserController() S:= NEWSERVER(U)

0

我會嘗試在車型更加纖薄變種傳播和控制器包,就像這樣:

// inside package controllers 

type UserModel interface { 
    Get() // the methods you need from the user model 
} 

type User struct { 
    UserModel 
} 

// inside package models 

type User struct { 
    // here the User Model 
} 


// inside package main 

import ".....controllers" 
import ".....models" 

func main() { 
    c := &controllers.User{&models.User{}} 
} 

// inside main_test.go 
import ".....controllers" 

type MockUser struct { 

} 


func TestX(t *testing.T) { 
    c := &controllers.User{&MockUser{}} 
} 

控制器測試中考慮ResponseRecorder of httptest package