api - 在不实际访问第三方 API 的情况下测试 Go (Golang) API 传出请求

标签 api testing go

我正在开发一个在内部后端和多个第三方 API 之间进行转换的 Go API。我试图了解如何在不实际访问外部 API 的情况下测试其功能。

例如,这是一个服务器,它处理传入的制作新歌曲的请求,并将请求发送到第三方 API:

package main

import (
        "bytes"
        "encoding/json"
        "fmt"
        "net/http"
)

var ThirdPartyApi = "http://www.coolsongssite.api"

type IncomingRequest struct {
        username string         `json:"username"`
        password string         `json:"password"`
        songs    []IncomingSong `json:"songs"`
}

type OutgoingRequest struct {
        username string         `json:"username"`
        password string         `json:"password"`
        songs    []OutgoingSong `json:"songs"`
}

type IncomingSong struct {
        artist string `json:"artist"`
        album  string `json:"album"`
        title  string `json:"title"`
}

type OutgoingSong struct {
        musician string `json:"musician"`
        record   string `json:"record"`
        name     string `json:"name"`
}

func main() {
        http.HandleFunc("/songs/create", createSong)
        http.ListenAndServe(":8080", nil)
}

func createSong(rw http.ResponseWriter, req *http.Request) {
         decoder := json.NewDecoder(req.Body)
         var incomingRequest IncomingRequest
         decoder.Decode(&incomingRequest)
         outgoingRequest := incomingRequestToOutgoingRequest(incomingRequest)

         r, _ := json.Marshal(outgoingRequest)
         request, _ := http.NewRequest("POST", ThirdPartyApi, bytes.NewBuffer(r))
         request.Header.Set("Content-Type", "application/json")

         client := http.Client{}

         response, _ := client.Do(request)
         fmt.Fprintln(rw, response)
}

func incomingRequestToOutgoingRequest(inc IncomingRequest) OutgoingRequest {
        outgoingRequest := OutgoingRequest{
                username: inc.username,
                password: inc.password,
        }

        for _, s := range inc.songs {
                outgoingRequest.songs = append(
                        outgoingRequest.songs, OutgoingSong{
                                musician: s.artist,
                                record:   s.album,
                                name:     s.title,
                        },
                )
        }

        return outgoingRequest
}

所以我可能会用这样的东西来访问在 localhost:8080 上运行的应用程序:

curl -X POST http://localhost:8080/songs/new --data \
'{"username": "<my-username>", "password": "<my-password>", "songs": \
["artist": "<song-artist>", "title": "<song-title>", "album": "<song-album>"]}'

我的问题是: 如何编写测试来测试发出的请求(在本例中为 http://www.coolsongssite.api)是否正确,而不实际发送它?

我是否应该重写 createSong 处理程序以便隔离 client.Do(request) 中发生的事情?

任何正确方向的帮助/建议/要点都将受到赞赏。

在这里,我可以像这样测试 incomingRequestToOutgoingRequest:

package main

import (
        "testing"
)

func TestincomingRequestToOutgoingRequest(t *testing.T) {
        incomingRequest := IncomingRequest{
                username: "myuser",
                password: "mypassword",
        }

        var songs []IncomingSong
        songs = append(
                songs, IncomingSong{
                artist: "White Rabbits",
                album:  "Milk Famous",
                title:  "I'm Not Me",
                },
        )

        outgoingRequest := incomingRequestToOutgoingRequest(incomingRequest)

        if outgoingRequest.songs[0].musician != "White Rabbits" {
                t.Error("Expected musican name to be 'White Rabbits'. Got: ", outgoingRequest.songs[0].musician)
        }
}

最佳答案

您可以像这样使用 net/http/httptest.NewServer:

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(200)
    w.Write([]byte(`desired response here`))
}))
defer ts.Close()
ThirdPartyURL = ts.URL
...
your test here

每当您的代码对 ThirdPartyURL 执行 HTTP 调用时,您将在定义的处理程序中收到请求,并可以返回您需要的任何响应。

关于api - 在不实际访问第三方 API 的情况下测试 Go (Golang) API 传出请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38339541/

相关文章:

iphone - 挂断智能手机后记录通话

unit-testing - 使用 Pester 模拟 [System.IO.Path]::IsPathRooted()?

c# - HttpClient - 不接受 DNS 更改

go - 如何使用 golang 运行 dir 命令?

api - 为什么PlayerVars不能再与YouTube API一起使用?

api - 404 状态码及其在常见的、几乎静态的 api 上的双重含义

javascript - 如何使用导入构造函数的外部库的 Jest 来测试模块

c - 在没有 WMI 的 Windows 中查找 MaxNumberOfProcesses

Json Unmarshal reflect.Type

api - 我应该为自定义错误使用什么 HTTP 状态代码?