Home > Backend Development > Golang > How to Unit Test HTTP Calls in Go using the `httptest` Package?

How to Unit Test HTTP Calls in Go using the `httptest` Package?

Susan Sarandon
Release: 2024-12-13 16:21:10
Original
570 people have browsed it

How to Unit Test HTTP Calls in Go using the `httptest` Package?

How to Test HTTP Calls in Go with httptest

Introduction

Unit testing is a crucial aspect of software development, and for Go programs, the httptest package provides a useful tool for testing HTTP calls. This article will demonstrate how to employ httptest to write unit tests for your Go code that makes HTTP requests.

The Challenge

Consider the following Go code:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "time"
)

type twitterResult struct {
    Results []struct {
        Text     string `json:"text"`
        Ids      string `json:"id_str"`
        Name     string `json:"from_user_name"`
        Username string `json:"from_user"`
        UserId   string `json:"from_user_id_str"`
    }
}

var (
  twitterUrl = "http://search.twitter.com/search.json?q=%23UCL"
  pauseDuration = 5 * time.Second
)

func retrieveTweets(c chan<- *twitterResult) {
    for {
        resp, err := http.Get(twitterUrl)
        if err != nil {
            log.Fatal(err)
        }

        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        r := new(twitterResult) //or &amp;twitterResult{} which returns *twitterResult
        err = json.Unmarshal(body, &amp;r)
        if err != nil {
            log.Fatal(err)
        }
        c <- r
        time.Sleep(pauseDuration)
    }

}

func displayTweets(c chan *twitterResult) {
    tweets := <-c
    for _, v := range tweets.Results {
        fmt.Printf("%v:%v\n", v.Username, v.Text)
    }

}

func main() {
    c := make(chan *twitterResult)
    go retrieveTweets(c)
    for {
        displayTweets(c)
    }

}
Copy after login

The objective is to write unit tests for this code, focusing on testing the HTTP requests made to retrieve tweets from Twitter's search API.

Solution Using httptest

The httptest package offers two types of tests: response tests and server tests. For this scenario, server tests are more suitable. Here's how to proceed:

  1. Create a Test Server:
func TestRetrieveTweets(t *testing.T){
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        fmt.Fprintln(w, `{"fake twitter json string"}`)
    }))
    defer ts.Close()
Copy after login

This code creates a test server that responds to HTTP requests with a predefined JSON response.

  1. Update the Original Code:
twitterUrl = ts.URL
Copy after login

In the original code, the twitterUrl variable is modified to point to the test server's URL instead of the actual Twitter API endpoint.

  1. Create a Channel:
c := make(chan *twitterResult)
Copy after login

A channel is used to communicate between the test goroutine and the main goroutine in the original code.

  1. Start a Goroutine to Retrieve Tweets:
go retrieveTweets(c)
Copy after login

This goroutine starts the process of retrieving tweets from the test server.

  1. Receive Tweets:
tweet := <-c
if tweet != expected1 {
    t.Fail()
}

tweet = <-c
if tweet != expected2 {
    t.Fail()
}
Copy after login

The test goroutine receives tweets from the channel and checks if they match the expected results.

Further Considerations

It's worth noting that the test is not verifying the content of the HTTP response. For a more thorough test, it would be necessary to compare the actual response with the expected response. Additionally, the test server should return a more realistic response structure to accurately simulate the actual Twitter API.

The above is the detailed content of How to Unit Test HTTP Calls in Go using the `httptest` Package?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template