我希望测试看起来像这样的PostUser函数(为简单起见省略了错误处理):
func PostUser(env *Env, w http.ResponseWriter, req *http.Request) error {
decoder := json.NewDecoder(req.Body)
decoder.Decode(&user)
if len(user.Username) < 2 || len(user.Username) > 30 {
return StatusError{400, errors.New("usernames need to be more than 2 characters and less than 30 characters")}
}
emailRe := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
if !emailRe.MatchString(user.Email) {
return StatusError{400, errors.New("invalid email address")}
}
if len(user.Password) < 8 {
return StatusError{400, errors.New("passwords need to be more at least 8 characters")}
}
hashedPassword,_ := bcrypt.GenerateFromPassword([]byte(user.Password), 12)
env.DB.InsertUser(user.Username, hashedPassword, user.Email) // need to mock this out
userData,_ := json.Marshal(user)
defer req.Body.Close()
w.Write(userData)
return nil
}
我的env.go
文件如下所示:
type Env struct {
DB *db.DB
}
我的db.go
文件如下所示:
type DB struct {
Session *mgo.Session
}
如何通过我的DB结构模拟InsertUser调用,以便我可以对PostUser进行单元测试?
答案 0 :(得分:0)
要使用模拟测试,您需要创建模拟可以实现的接口。当然,您替换模拟的结构也需要实现接口的所有方法,以便它们可以自由地互换。
例如,您可以拥有一个界面:
type DBInterface interface {
InsertUser(string, string, string)
//all other methods on the DB struct here
}
然后你的DB结构已经实现了接口的所有方法。从那里你可以创建一个也实现接口的模拟结构。
type DBMock struct {}
func (dbm *DBMock) InsertUser(username, password, email string) {
//whatever mock functionality you want here
return
}
//all other methods also implemented.
然后你可以改变env以获得指向DBInterface而不是DB的指针。当您设置要传递给处理程序的env时,在生产版本中使用DB结构并在测试中使用DBMock结构。