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 !
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 ?
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!