Heim >Backend-Entwicklung >Golang >Die Golang-Simulation erzwingt Änderungen an Funktionsdefinitionen

Die Golang-Simulation erzwingt Änderungen an Funktionsdefinitionen

WBOY
WBOYnach vorne
2024-02-12 12:33:081247Durchsuche

Die Golang-Simulation erzwingt Änderungen an Funktionsdefinitionen

Der PHP-Editor Xiaoxin bietet Ihnen heute eine Einführung in die Golang-Simulation, bei der Funktionsdefinitionen zwangsweise geändert werden. Golang ist eine effiziente und prägnante Programmiersprache mit einem leistungsstarken Typsystem. In einigen Fällen müssen wir jedoch möglicherweise die Definition einer vorhandenen Funktion ändern, um bestimmte Anforderungen zu erfüllen. In diesem Artikel erfahren Sie, wie Sie die Methode zum erzwungenen Ändern der Funktionsdefinition in Golang simulieren können.

Frageninhalt

Ich habe folgende Funktion:

func getprice(date string) {
  url := (fmt.printf("http://endponint/%s", date))
    resp, err := http.get(url)
    // unmarshall body and get price
    return price
}

Um diese Funktion einem Unit-Test zu unterziehen, musste ich eine Umgestaltung vornehmen zu:

func getprice(client httpclient, date string) {
  url := (fmt.printf("http://endponint/%s", date))
    resp, err := client.get(url)
    // unmarshall body and get price
    return price
}

Mein Test sieht so aus:

type MockClient struct {
    Response *http.Response
    Err      error
}

func (m *MockClient) Get(url string) (*http.Response, error) {
    return m.Response, m.Err
}

mockResp := &http.Response{
    StatusCode: http.StatusOK,
    Body:       ioutil.NopCloser(strings.NewReader("mock response")),
}

client := &MockClient{
    Response: mockResp,
    Err:      nil,
}

data, err := getData(client, "http://example.com")

Ist das die einzige Möglichkeit, unterwegs zu testen? Gibt es nicht eine Möglichkeit, die API zu verspotten, die nicht in die Funktion eingefügt wird?

Workaround

Der idiomatische Weg, HTTP-Tests mit go durchzuführen, ist die Verwendung von http/httptest ( Beispiel)

In Ihrem Fall müssen Sie lediglich die Basis-URL injizierbar machen:

var apiendpoint = "http://endpoint/"

func getprice(date string) (int, error) {
  url := (fmt.printf("%s/%s", apiendpoint, date))
  resp, err := http.get(url)
  // unmarshall body and get price
  return price, nil
}

Dann gilt bei jedem Test:

srv := httptest.newserver(http.handlerfunc(func(w http.responsewriter, r *http.request) {
    // write the expected response to the writer
}))
defer srv.close()
apiendpoint = srv.url
price, err := getprice("1/1/2023")
// handle error, check return

Ein besseres Design besteht darin, Ihre API auf der Clientseite zu verpacken. struct 中,并使 getprice Seien Sie die Empfängermethode:

type priceclient struct {
    endpoint string
}

func (pc *priceclient) getprice(date string) (int, error) {
  url := (fmt.printf("%s/%s", pc.endpoint, date))
  resp, err := http.get(url)
  // unmarshall body and get price
  return price, nil
}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // Write the expected response to the writer
}))
defer srv.Close()
c := &PriceClient{Endpoint: srv.URL}
price, err := c.GetPrice("1/1/2023")
// Handle error, check return

Für zukünftige Referenzen sollten Sie sich auch gomock ansehen, da die meisten anderen Mocking-Probleme, auf die Sie stoßen, keine integrierten Lösungen in der Sprache haben.

Das obige ist der detaillierte Inhalt vonDie Golang-Simulation erzwingt Änderungen an Funktionsdefinitionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen