dsfjk44656 2017-08-21 00:19
浏览 64

如何正确测试在其中调用另一个函数的处理程序

I am looking to test the PostUser function that looks something like this (error handling omitted for simplicity):

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
}

My env.go file looks like this:

type Env struct {
    DB *db.DB
}

My db.go file looks like this:

type DB struct {
    Session *mgo.Session
}

How do I mock the InsertUser call by my DB struct, so that I can unit test the PostUser?

  • 写回答

1条回答 默认 最新

  • douzun4443 2017-08-21 14:40
    关注

    To use mocks for testing you need to create an interface that your mock can implement. Naturally, the struct you're replacing the mock with also needs to implement all the methods of the interface so that they are freely interchangeable.

    For example, you could have an interface:

    type DBInterface interface {
        InsertUser(string, string, string)
        //all other methods on the DB struct here  
    }
    

    Then your DB struct already implements all the methods of the interface. From there you can create a mock struct that also implements the interface.

    type DBMock struct {}
    
    func (dbm *DBMock) InsertUser(username, password, email string) {
        //whatever mock functionality you want here
        return
    } 
    
    //all other methods also implemented.
    

    Then you can alter env to have a pointer to a DBInterface instead of a DB. When you setup the env to be passed into the handler, in the production version use the DB struct and in testing use the DBMock struct.

    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么