当前位置: 首页 > news >正文

网站建设域名空间模拟网站建设软件有哪些

网站建设域名空间,模拟网站建设软件有哪些,seo网络推广教程,类似抖音网站开发费用文章目录 一、构建 HTTP server1.1 model.go1.2 server.go1.3 curl 验证 server 功能1.3.1 新建1.3.2 查询1.3.3 更新1.3.4 删除 二、httptest 测试2.1 完整示例2.2 实现逻辑2.3 其他示例2.4 用 TestMain 避免重复的测试代码2.5 gin 框架的 httptest 一、构建 HTTP server 1.1… 文章目录 一、构建 HTTP server1.1 model.go1.2 server.go1.3 curl 验证 server 功能1.3.1 新建1.3.2 查询1.3.3 更新1.3.4 删除 二、httptest 测试2.1 完整示例2.2 实现逻辑2.3 其他示例2.4 用 TestMain 避免重复的测试代码2.5 gin 框架的 httptest 一、构建 HTTP server 1.1 model.go package mainimport (errorstime )var TopicCache make([]*Topic, 0, 16)type Topic struct {Id int json:idTitle string json:titleContent string json:contentCreatedAt time.Time json:created_at }// 从数组中找到一项, 根据 id 找到数组的下标 func FindTopic(id int) (*Topic, error) {if err : checkIndex(id); err ! nil {return nil, err}return TopicCache[id-1], nil }// 创建一个 Topic 实例, 没有输入参数, 内部根据 Topic 数组的长度来确定新 Topic 的 id func (t *Topic) Create() error {// 初始时len 为 0, id 为 1, 即数组下标为0时并不放置元素, 而数组从下标为1才开始放置元素t.Id len(TopicCache) 1 // 忽略用户传入的 id, 而是根据数组的长度, 决定此项的 Idt.CreatedAt time.Now()TopicCache append(TopicCache, t) // 初始时数组为空, 放入的第一个元素是 Id 1return nil }// 更新一个 Topic 实例, 通过 id 找到数组下标, 最终改的还是数组里的值 func (t *Topic) Update() error {if err : checkIndex(t.Id); err ! nil {return err}TopicCache[t.Id-1] treturn nil }func (t *Topic) Delete() error {if err : checkIndex(t.Id); err ! nil {return err}TopicCache[t.Id-1] nilreturn nil }func checkIndex(id int) error {if id 0 len(TopicCache) id-1 {return errors.New(The topic is not exists!)}return nil }1.2 server.go package mainimport (encoding/jsonnet/httppathstrconv )func main() {http.HandleFunc(/topic/, handleRequest)http.ListenAndServe(:2017, nil) }// main handler function func handleRequest(w http.ResponseWriter, r *http.Request) {var err errorswitch r.Method {case http.MethodGet:err handleGet(w, r)case http.MethodPost:err handlePost(w, r)case http.MethodPut:err handlePut(w, r)case http.MethodDelete:err handleDelete(w, r)}if err ! nil {http.Error(w, err.Error(), http.StatusInternalServerError)return} }// 获取一个帖子 // 如 GET /topic/1 func handleGet(w http.ResponseWriter, r *http.Request) error {// 用户输入的 url 中有 id, 通过 path.Base(r.URL.Path) 获取 idid, err : strconv.Atoi(path.Base(r.URL.Path))if err ! nil {return err}topic, err : FindTopic(id)if err ! nil {return err}// 序列化结果并输出output, err : json.MarshalIndent(topic, , \t\t)if err ! nil {return err}w.Header().Set(Content-Type, application/json)w.Write(output)return nil }// 增加一个帖子 // POST /topic/ func handlePost(w http.ResponseWriter, r *http.Request) (err error) {// 构造长度为 r.ContentLength 的缓冲区body : make([]byte, r.ContentLength)// 读取到缓冲区r.Body.Read(body)// 反序列化到对象var topic new(Topic)err json.Unmarshal(body, topic)if err ! nil {return}// 执行操作err topic.Create()if err ! nil {return}w.WriteHeader(http.StatusOK)return }// 更新一个帖子 // PUT /topic/1 func handlePut(w http.ResponseWriter, r *http.Request) error {id, err : strconv.Atoi(path.Base(r.URL.Path))if err ! nil {return err}topic, err : FindTopic(id)if err ! nil {return err}body : make([]byte, r.ContentLength)r.Body.Read(body)json.Unmarshal(body, topic)err topic.Update()if err ! nil {return err}w.WriteHeader(http.StatusOK)return nil }// 删除一个帖子 // DELETE /topic/1 func handleDelete(w http.ResponseWriter, r *http.Request) (err error) {id, err : strconv.Atoi(path.Base(r.URL.Path))if err ! nil {return}topic, err : FindTopic(id)if err ! nil {return}err topic.Delete()if err ! nil {return}w.WriteHeader(http.StatusOK)return }1.3 curl 验证 server 功能 1.3.1 新建 curl -i -X POST http://localhost:2017/topic/ -H content-type: application/json -d {title:a, content:b}HTTP/1.1 200 OK Date: Mon, 11 Mar 2024 02:54:08 GMT Content-Length: 01.3.2 查询 curl -i -X GET http://localhost:2017/topic/1HTTP/1.1 200 OK Content-Type: application/json Date: Mon, 11 Mar 2024 03:00:11 GMT Content-Length: 99{id: 1,title: a,content: b,created_at: 2024-03-11T10:59:44.04302908:00 }1.3.3 更新 curl -i -X PUT http://localhost:2017/topic/1 -H content-type: application/json -d {title: c, content: d}HTTP/1.1 200 OK Date: Mon, 11 Mar 2024 03:01:51 GMT Content-Length: 0curl -i -X GET http://localhost:2017/topic/1 HTTP/1.1 200 OK Content-Type: application/json Date: Mon, 11 Mar 2024 03:01:54 GMT Content-Length: 99{id: 1,title: c,content: d,created_at: 2024-03-11T10:59:44.04302908:00 }1.3.4 删除 curl -i -X DELETE http://localhost:2017/topic/1HTTP/1.1 200 OK Date: Mon, 11 Mar 2024 03:03:41 GMT Content-Length: 0curl -i -X GET http://localhost:2017/topic/1 HTTP/1.1 200 OK Content-Type: application/json Date: Mon, 11 Mar 2024 03:04:27 GMT Content-Length: 4null二、httptest 测试 上文通过 curl 自测了 controller现在通过 net/http/httptest 测试这种测试方式其实是没有 HTTP 调用的是通过将 handler() 函数绑定到 url 上实现的。 2.1 完整示例 package mainimport (net/httpnet/http/httpteststringstesting )func TestHandlePost(t *testing.T) {// mux 是多路复用器的意思mux : http.NewServeMux()mux.HandleFunc(/topic/, handleRequest) // 将 [业务的 handleRequest() 函数] 注册到 mux 的 /topic/ 路由上// 构造一个请求reader : strings.NewReader({title:e, content:f})r, _ : http.NewRequest(http.MethodPost, /topic/, reader)// 构造一个响应 (httptest.ResponseRecorder 实现了 http.ResponseWriter 接口)w : httptest.NewRecorder()mux.ServeHTTP(w, r)//handleRequest(w, r)// 获取响应结果resp : w.Result()if resp.StatusCode ! http.StatusOK {t.Errorf(Expected status OK; got %v, resp.Status)} }2.2 实现逻辑 实现逻辑如下 首先配置路由将 /topic 的请求都路由给 handleRequest() 函数实现。 mux : http.NewServeMux() mux.HandleFunc(/topic/, handleRequest)因为 handleRequest(w http.ResponseWriter, r *http.Request) 函数的签名是 w 和 r 两个参数所以为了测试需要构造这两个参数实例。 因为 httptest.ResponseRecorder 实现了 http.ResponseWriter 接口所以可以用 httptest.NewRecorder() 表示 w。 准备好之后就可以执行了 可以只调用 handleRequest(w, r)也可以调用 mux.ServeHTTP(w, r)其内部也会调用 handleRequest(w, r)这会更完整的测试整个流程。 最后通过 go test -v 可以执行测试。 $ go test -v RUN TestHandlePost --- PASS: TestHandlePost (0.00s) PASS ok benchmarkdemo 0.095s2.3 其他示例 func TestHandleGet(t *testing.T) {mux : http.NewServeMux()mux.HandleFunc(/topic/, handleRequest)r, _ : http.NewRequest(http.MethodGet, /topic/1, nil)w : httptest.NewRecorder()mux.ServeHTTP(w, r)resp : w.Result()if resp.StatusCode ! http.StatusOK {t.Errorf(Expected status OK; got %v, resp.Status)}topic : new(Topic)json.Unmarshal(w.Body.Bytes(), topic)if topic.Id ! 1 {t.Errorf(cannot get topic by id)} }注意因为数据没有落地存储为了保证后面的测试正常请将 TestHandlePost 放在最前面。 如果 go test -v 测试整个包的话TestHandlePost 和 TestHandleGet 两个单测都能成功但如果分开测试的话只有 TestHandlePost 能成功而 TestHandleGet 会失败因为没有 POST 创建流程而只有 GET 创建流程的话在业务逻辑的数组中找不到 id 1 的项就会报错 2.4 用 TestMain 避免重复的测试代码 细心的朋友应该会发现上面的测试代码有重复比如 mux : http.NewServeMux() mux.HandleFunc(/topic/, handleRequest)以及 w : httptest.NewRecorder()这正好是前面学习的 setup 可以做的事情因此可以使用 TestMain 来做重构。实现如下 var w *httptest.ResponseRecorderfunc TestMain(m *testing.M) {w httptest.NewRecorder()os.Exit(m.Run()) }2.5 gin 框架的 httptest package serviceimport (fmtlognet/httpnet/http/httpteststringstestinggithub.com/gin-gonic/gin )type userINfo struct {ID uint64 json:idName string json:name }func handler(c *gin.Context) {var info userINfoif err : c.ShouldBindJSON(info); err ! nil {log.Panic(err)}fmt.Println(info)c.Writer.Write([]byte({status: 200})) }func TestHandler(t *testing.T) {rPath : /userrouter : gin.Default()router.GET(rPath, handler)req, _ : http.NewRequest(GET, rPath, strings.NewReader({id: 1,name: joe}))w : httptest.NewRecorder()router.ServeHTTP(w, req)t.Logf(status: %d, w.Code)t.Logf(response: %s, w.Body.String()) }
http://www.zqtcl.cn/news/721406/

相关文章:

  • 家乡网站建设策划书angular做的网站
  • 土豆网网站开发源代码thinkphp5做的网站
  • lng企业自建站wordpress 分页 美化
  • 手机版网站如何做新闻类网站怎么做百度推广
  • 网站开发工程师 上海合肥网站到首页排名
  • 商城网站后续费用请人代做谷歌外贸网站
  • 汽车网站有哪些3d家装效果图制作软件
  • 荆门做网站公众号的公司网站百度不收录的原因
  • 专门做羽毛球的网站福州seo网站排名
  • 网站返回503的含义是门户网站开发合同
  • 自己做网站的成本要哪些东西wordpress模板如何管理系统
  • 做一般的网站要多久wordpress写文章页面无法显示
  • 人和兽做的网站视频汽车建设网站开发流程
  • 长春市建设工程造价管理协会网站厦门网站建设费用
  • 广东建设信息公开网站怎样策划一个营销型网站
  • 魔兽做图下载网站如何经营一个购物网站
  • 深圳做网站哪个平台好一级消防工程师考试题型
  • 网站婚礼服务态网站建设论文网站设计有限公司是干嘛的
  • 邯郸网站建设效果好广西做网站的公司
  • 网站logo上传营销型网站制作方案
  • 小说网站静态模板站长工具seo综合查询adc
  • 北京响应式网站做logo那个网站
  • 如何申请免费网站空间刚察县wap网站建设公司
  • 哪里有网站推广软件免费推广seo策略方法
  • 阿里云备案网站 网站名称怎么写京icp备案查询
  • 网站开发岗位思维导图alexa排名
  • 自适应网站建设济南济南网站建设公司
  • 巴州网站建设库尔勒网站建设钟爱网络杭州微信网站制作
  • 52做网站南京市住房城乡建设门户网站
  • 网站开发精品课程贵阳市白云区官方网站