基于GO编写一个http服务,接收JSON数组[“a“,“b“,“c“],需要返回[false,false,false],在接收[“b“, “c“]返回JSON [true,true]并编写测试用例

http server

package main

import (
	"encoding/json"
	"io"
	"log"
	"net/http"
	"sync"
)

var (
	cacheObj             = NewCache()
	readRequestBodyError = "read body error"
	unmarshalBodyError   = "unmarshal body error"
	marshalResultError   = "unmarshal result error"
)

func NewCache() *cache {
	return &cache{Data: make(map[string]struct{})}
}

type cache struct {
	Data map[string]struct{}
	lock sync.RWMutex
}

func (c *cache) exists(key string) bool {
	c.lock.RLock()
	_, ok := c.Data[key]
	c.lock.RUnlock()
	return ok
}

func (c *cache) set(key string) {
	c.lock.Lock()
	c.Data[key] = struct{}{}
	c.lock.Unlock()
}

func echoHandler(writer http.ResponseWriter, request *http.Request) {
	body, err := io.ReadAll(request.Body)
	if err != nil {
		http.Error(writer, readRequestBodyError, http.StatusInternalServerError)
		return
	}

	var array []string
	err = json.Unmarshal(body, &array)
	if err != nil {
		http.Error(writer, unmarshalBodyError, http.StatusInternalServerError)
		return
	}

	result := make([]bool, len(array))
	for index, value := range array {
		if ok := cacheObj.exists(value); !ok {
			cacheObj.set(value)
		} else {
			result[index] = ok
		}
	}

	b, err := json.Marshal(result)
	if err != nil {
		http.Error(writer, marshalResultError, http.StatusInternalServerError)
		return
	}

	writer.Header().Add("Content-Type", "Application/json")
	writer.WriteHeader(http.StatusOK)
	writer.Write(b)
}

func main() {
	http.HandleFunc("/echo", echoHandler)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal(err)
	}
}

test case

package main

import (
	"io"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
)

func TestEchoServer(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(echoHandler))
	defer srv.Close()

	cases := []struct {
		req string
		exp string
	}{
		{req: `["a", "b", "c"]`, exp: `[false,false,false]`},
		{req: `["a", "b", "c", "d"]`, exp: `[true,true,true,false]`},
		{req: `["m", "d", "a"]`, exp: `[false,true,true]`},
		{req: `["a", "m", "s","l"]`, exp: `[true,true,false,false]`},
	}

	for _, cs := range cases {
		resp, err := http.Post(srv.URL, "application/json", strings.NewReader(cs.req))
		if err != nil {
			t.Fatalf("post error: %v", err)
		}

		if resp.StatusCode != http.StatusOK {
			t.Errorf("reponse code error: %d", resp.StatusCode)
		}

		res, err := io.ReadAll(resp.Body)
		if err != nil {
			t.Errorf("read all error: %v", err)
		}

		str := string(res)
		if str != cs.exp {
			t.Errorf("expected response body %s, but got %s", cs.exp, str)
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值