Как правильно прикрепить файл к POST-запросу в тестовой среде - PullRequest
0 голосов
/ 12 февраля 2020

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

Вот как я прикрепляю файл в моем тестовом запросе:

    file := new(bytes.Buffer)

    f, err := os.Open("myfile.csv")
    if err != nil {
        t.Fatal(err)
    }

    defer f.Close()
    io.Copy(f, file)

    req, err := http.NewRequest("POST", "/upload", file)

Я получил ошибку: "http: no such file"

Когда я попадаю на строку, в которой file, _, err := r.FormFile("file") в контроллере.

Мне также было интересно, является ли «file» неправильный ключ для FormFile, поэтому я также попытался «fileupload», и это то же самое. Немного запутался в этом.

Так что я также попытался собрать "csv" на лету с помощью csv.NewWriter, и это дало похожий результат.

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


Обновление: вот еще тест для ясности того, как я обслуживаю запрос. Благодаря комментарию Флимзи, я удалил io.Copy, и теперь я перешел к новой ошибке:

    f, err := os.Open("myfile.csv")
    if err != nil {
        t.Fatal(err)
    }

    defer f.Close()

    mw := multipart.NewWriter(f)
    mw.Close()

    req, err := http.NewRequest("POST", "/upload", f)
    req.Header.Add("Content-Type", mw.FormDataContentType())

    // add the discountID URL var
    req = mux.SetURLVars(req, map[string]string{
        "discountID": discountID,
    })

    rr := httptest.NewRecorder()

    controller := generateDiscountsController()

    // Set middleware memberInfo context
    gContext.Set(req, "memberInfo", memberInfo)

    // Pass appropriate controller method to http handler in this case
    // Get discount
    handler := http.HandlerFunc(controller.ImportCSV)
    handler.ServeHTTP(rr, req)
    resp := response.GetBodyMessage(rr.Body)

    assert.Equal(t, 201, rr.Code)
    assert.Equal(t, "success", resp)

ошибка: "multipart: NextPart: EOF" эта ошибка раньше фиксировалась в моем контроллере на err := r.ParseMultipartForm(32 << 20)


В моем контроллере запрос обрабатывается здесь:

func (d *APIDiscount) ImportCSV(w http.ResponseWriter, r *http.Request) {
    var buf bytes.Buffer
    var firstTen [][]string
    var columns []string

    defer buf.Reset()

    vars := mux.Vars(r)
    // using csv writer is safer and better at catching errors than io.Copy
    csvData := csv.NewWriter(&buf)
    memberInfo := gContext.Get(r, "memberInfo").(*entity.MemberInfo)

    err := r.ParseMultipartForm(32 << 20) // max 32 MB <-- Catching here in the test, but not when I send the request through postman on my local server with the same file
    if err != nil {
        response.InternalError.Send(w, r, memberInfo, 400)
    }

    file, _, err := r.FormFile("file") // <-- Used to catch here when I used io.Copy
    if err != nil {
        if err == http.ErrMissingFile {
            response.MissingFile.Send(w, r, memberInfo, 400)
            return
        }
        response.FileNotAccepted.Send(w, r, memberInfo, 400)
        return
    }
// ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...