Проверка работоспособности запроса API golang - PullRequest
1 голос
/ 05 февраля 2020

Я пытаюсь добавить тесты в мой golang проект. Моя программа сохраняет JSON данные в CSV-файл. Что я делаю, так это отображаю свои данные на экране (см. Комментарий // STDOUT) и использую канал, который автоматически создает нужный файл форматирования: go run main.go > file.csv, например, здесь я сохраняю данные в файл csv с именем file.csv

Чтобы быть более понятным, вот мой код:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "strconv"
    "strings"
)

type People struct {
    Name string
    Craft string
}

type General struct {
    People []People
    Number int
    Message string
}

func main() {
    // Reading data from JSON File  
    response, err := http.Get("http://api.open-notify.org/astros.json")
    if err != nil {
        fmt.Printf("The Http request failed with error %s\n", err)
    }

    data,_ := ioutil.ReadAll(response.Body)
    //fmt.Println(string(data))
    // Unmarshal JSON data
    var general General
    json.Unmarshal([]byte(data), &general)
    var header []string
    header = append(header, "Number")
    header = append(header, "Message")
    header = append(header, "Name")
    header = append(header, "Craft")
    fmt.Println(strings.Join(header, ","))
    for _, obj := range general.People {    
        var record []string
        record = append(record, strconv.Itoa(general.Number), general.Message)
        record = append(record, obj.Name, obj.Craft)
        fmt.Println(strings.Join(record, ",")) // STDOUT 
        record = nil
    }
}

Итак, на моем экране я получаю этот вывод, как и ожидалось:

Number,Message,Name,Craft
6,success,Christina Koch,ISS
6,success,Alexander Skvortsov,ISS
6,success,Luca Parmitano,ISS
6,success,Andrew Morgan,ISS
6,success,Oleg Skripochka,ISS
6,success,Jessica Meir,ISS

Так что мне интересно, как Я могу проверить, правильно ли отображаются выходные данные, которые я ожидаю.

Я попытался написать файл main_test.go, но не могу найти, как правильно его кодировать.

package main

import (
    "testing"
    "net/http"
    "net/http/httptest"
)

func TestGetEntries(t *testing.T) {
    response, err := http.Get("http://api.open-notify.org/astros.json")
    if err != nil {
        t.Fatal(err)
    }
    // I don't know how to deal with this part:
    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(main)
    handler.ServeHTTP(rr, req)
    if status := rr.Code; status != http.StatusOK {
        t.Errorf("handler returned wrong status code: got %v want %v",
            status, http.StatusOK)
    }

    // Check the response body is what we expect.
    // For example I want to test the first line:
    expected := `6,success,Christina Koch,ISS`
    if rr.Body.String() != expected {
        t.Errorf("handler returned unexpected body: got %v want %v",
            rr.Body.String(), expected)
    }
}

1 Ответ

0 голосов
/ 06 февраля 2020

Позвольте мне предупредить, что мне могут нравиться тесты слишком много, нормальные люди обычно не слишком много с этим справляются.

Обычно я стараюсь избегать тестирования чего-либо, что будет напечатано в stdout в main. Будет проще проверить, был ли контент возвращен из функции перед печатью в stdout.

Иногда я действительно хочу, чтобы мое тестовое покрытие было основным, и в этом случае можно использовать тестовую функцию с префиксом «Пример», это плохое решение, но довольно простое в использовании.

main. go

package main
import "fmt"
func main(){
   fmt.Println("Hello World")
}

main_test. go

package main
func ExampleMain(){
   main()
   // Output:
   // Hello World
}

С вашим кодом «Пример» должно быть:

package main
func ExampleMain(){
   main()
   // Output:
   // Number,Message,Name,Craft
   // 6,success,Christina Koch,ISS
   // 6,success,Alexander Skvortsov,ISS
   // 6,success,Luca Parmitano,ISS
   // 6,success,Andrew Morgan,ISS
   // 6,success,Oleg Skripochka,ISS
   // 6,success,Jessica Meir,ISS
}

Это простой способ тестирования, но его сложно обновить, поэтому мне не очень нравится.

Я бы предпочел что-то еще гибкий как это:
основной. go

package main

import "fmt"

func main() {

    txt := helloWorld()

    fmt.Println(txt)
}

func helloWorld() string {
    return "Hello World"
}

main_test. go

package main

import "testing"

func Test_helloWorld(t *testing.T) {
    tests := []struct {
        name string
        want string
    }{
        {
            name: "A simple Test",
            want: "Hello World",
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := helloWorld(); got != tt.want {
                t.Errorf("helloWorld() = %v, want %v", got, tt.want)
            }
        })
    }
}

Это предпочтительно не запрашивать внешние услуги, когда это возможно, на ваших тестах, конечно, если вы считаете, что лучше запросить их в своем тесте любая причина, по которой вы знаете, это тоже нормально, но если вы чувствуете, что было бы лучше, если бы это было издевательской просьбой, и вы не знаете, как я был бы рад, чтобы предложить некоторые способы сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...