duanjiyun7391 2019-05-17 15:30
浏览 36
已采纳

如何在Go中为可以进行单元测试的休息服务设置Mongo DB?

I am setting up a rest service in go using MongoDB and mux routers. I am running into issues on how to best set this up to allow for unit/integration testing in a separate database.

I have tried setting up the database in the Init() function but this is giving me issues when trying to set up unit tests using a test DB.

Here are some examples of where I am at right now. I am trying to use a method to connect to the database before posting so in my test I can connect to a different testing database.

type user struct {
    name string `json:"name"`
    age  int    `json:"age"`
}

type database struct {
    db *mongo.Database
}

func ConnectToDB() (*database, error) {
    client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        return nil, err
    }

    if err := client.Connect(context.Background()); err != nil {
        return nil, err
    }

    database := &database{
        db: client.Database("PMBaseGo"),
    }

    return database, nil
}

func PostUser(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    //Retrieving request body
    var user user
    _ = json.NewDecoder(r.Body).Decode(&user)
    //Posting Company.
    err := PostUserToDB(user)
    //Error Handling
    if err != nil {
        fmt.Println(err)
        w.WriteHeader(500)
    }
}

func (d *database) connPostUserToDB(user user) error {
    _, err := d.db.Collection("companies").InsertOne(context.Background(), user)
    if err != nil {
        return err
    }
    return nil
}

func main() {
    _, _ = ConnectToDB()
    r := mux.NewRouter()

    r.HandleFunc("/user", PostUser).Methods("POST")

    fmt.Println("Application Running...")
    log.Fatal(http.ListenAndServe("localhost:8081", r))
}

The issue I am at right now is trying to call the PostUserToDB method in the PostUser function.

I'm starting to think the issue lies prior to this in how I am going about connecting to the DB.

  • 写回答

1条回答 默认 最新

  • duanping1920 2019-05-17 16:00
    关注

    Make your handler a method on a struct that holds the handler's dependencies:

    type server struct {
        srv *service
    }
    
    type service struct {
        db *mongo.Database
    }
    
    func (s *server) PostUser(w http.ResponseWriter, r *http.Request) {
        // Create user struct from request data...
    
        if err := s.srv.CreateUser(u); err != nil {
            // Error response.
        }
    
        // Success response.
    }
    
    func (s *service) CreateUser(u *user) error {
        // ...
        _, err := d.db.Collection("foo").InsertOne(r.Context(), user)
        return err
    }
    
    func main() {
        s := &server{
            srv: &service{
                db: getMongoDatabase(),
            },
        }
    
        r := mux.NewRouter()
        r.HandleFunc("/user", s.PostUser).Methods("POST")
    
        log.Fatal(http.ListenAndServe("localhost:8081", r))
    }
    

    In your test code, you can simply inject a different database to have your tests operate on that database.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改