Maison >développement back-end >Golang >La simulation Golang impose des modifications aux définitions de fonctions

La simulation Golang impose des modifications aux définitions de fonctions

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBavant
2024-02-12 12:33:081305parcourir

La simulation Golang impose des modifications aux définitions de fonctions

L'éditeur PHP Xiaoxin vous propose aujourd'hui une introduction à la simulation Golang en modifiant de force les définitions de fonctions. Golang est un langage de programmation efficace et concis doté d'un système de types puissant. Cependant, dans certains cas, nous pouvons être amenés à modifier la définition d'une fonction existante pour répondre à des besoins spécifiques. Cet article vous présentera comment simuler la méthode de modification forcée de la définition de fonction dans Golang. Explorons-la ensemble !

Contenu de la question

J'ai la fonction suivante :

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

Afin de tester unitairement cette fonction, j'ai été obligé de refactoriser pour :

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
}

Mon test ressemble à ceci :

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")

Est-ce la seule façon de tester en go ? N'existe-t-il pas un moyen de se moquer de l'API qui n'est pas injectée dans la fonction ?

Solution de contournement

La manière idiomatique de faire des tests http avec go est d'utiliser http/httptest ( Exemple)

Dans votre cas, il vous suffit de rendre l'url de base injectable :

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
}

Puis dans chaque 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

Une meilleure conception consiste à envelopper votre API côté client struct 中,并使 getprice Soyez la méthode du récepteur :

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

Pour référence future, vous devriez également jeter un œil à gomock, car la plupart des autres problèmes moqueurs que vous rencontrerez n'ont pas de solution intégrée dans le langage.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer