鸿蒙传说
services/message.go:type messageService struct { HttpClient http.Client BaseURL string}func (m *messageService) MarkAllMessages(accesstoken string) []*model.MarkedMessage { endpoint := m.BaseURL + "/message/mark_all" var res model.MarkAllMessagesResponse if err := m.HttpClient.Post(endpoint, &MarkAllMessagesRequestPayload{Accesstoken: accesstoken}, &res); err != nil { fmt.Println(err) return res.MarkedMsgs } return res.MarkedMsgs}我们传递res给m.HttpClient.Post方法。在此方法中,res将填充json.unmarshal方法。mocks/http.go:package mocksimport ( "io" "github.com/stretchr/testify/mock")type MockedHttp struct { mock.Mock}func (m *MockedHttp) Get(url string, data interface{}) error { args := m.Called(url, data) return args.Error(0)}func (m *MockedHttp) Post(url string, body interface{}, data interface{}) error { args := m.Called(url, body, data) return args.Error(0)}services/message_test.go:package services_testimport ( "errors" "reflect" "strconv" "testing" "github.com/stretchr/testify/mock" "github.com/mrdulin/gqlgen-cnode/graph/model" "github.com/mrdulin/gqlgen-cnode/services" "github.com/mrdulin/gqlgen-cnode/mocks")const ( baseURL string = "http://localhost/api/v1" accesstoken string = "123")func TestMessageService_MarkAllMessages(t *testing.T) { t.Run("should mark all messaages", func(t *testing.T) { testHttp := new(mocks.MockedHttp) var res model.MarkAllMessagesResponse var markedMsgs []*model.MarkedMessage for i := 1; i <= 3; i++ { markedMsgs = append(markedMsgs, &model.MarkedMessage{ID: strconv.Itoa(i)}) } postBody := services.MarkAllMessagesRequestPayload{Accesstoken: accesstoken} testHttp.On("Post", baseURL+"/message/mark_all", &postBody, &res).Return(nil).Run(func(args mock.Arguments) { arg := args.Get(2).(*model.MarkAllMessagesResponse) arg.MarkedMsgs = markedMsgs }) service := services.NewMessageService(testHttp, baseURL) got := service.MarkAllMessages(accesstoken) want := markedMsgs testHttp.AssertExpectations(t) if !reflect.DeepEqual(got, want) { t.Errorf("got wrong return value. got: %#v, want: %#v", got, want) } }) t.Run("should print error and return empty slice", func(t *testing.T) { var res model.MarkAllMessagesResponse testHttp := new(mocks.MockedHttp) postBody := services.MarkAllMessagesRequestPayload{Accesstoken: accesstoken} testHttp.On("Post", baseURL+"/message/mark_all", &postBody, &res).Return(errors.New("network")) service := services.NewMessageService(testHttp, baseURL) got := service.MarkAllMessages(accesstoken) var want []*model.MarkedMessage testHttp.AssertExpectations(t) if !reflect.DeepEqual(got, want) { t.Errorf("got wrong return value. got: %#v, want: %#v", got, want) } })}在单元测试用例中,我们填充了res# Call.Run方法并将返回值(res.MarkedMsgs)分配service.MarkAllMessages(accesstoken)给got变量。单元测试结果和覆盖率:=== RUN TestMessageService_MarkAllMessages--- PASS: TestMessageService_MarkAllMessages (0.00s)=== RUN TestMessageService_MarkAllMessages/should_mark_all_messaages TestMessageService_MarkAllMessages/should_mark_all_messaages: message_test.go:39: PASS: Post(string,*services.MarkAllMessagesRequestPayload,*model.MarkAllMessagesResponse) --- PASS: TestMessageService_MarkAllMessages/should_mark_all_messaages (0.00s)=== RUN TestMessageService_MarkAllMessages/should_print_error_and_return_empty_slicenetwork TestMessageService_MarkAllMessages/should_print_error_and_return_empty_slice: message_test.go:53: PASS: Post(string,*services.MarkAllMessagesRequestPayload,*model.MarkAllMessagesResponse) --- PASS: TestMessageService_MarkAllMessages/should_print_error_and_return_empty_slice (0.00s)PASScoverage: 5.6% of statements in ../../gqlgen-cnode/...Process finished with exit code 0