Golang测试文件上传功能的方法与实践
Golang测试文件上传功能的方法与实践 大家好 请告诉我如何为我的简单文件上传处理程序正确编写测试
func UploadFile(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(1024)
file, _, err := r.FormFile("uploadFile")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Invalid file to upload")
return
}
defer file.Close()
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Read file error - Invalid data in file")
return
}
}
我想从包内的tmp文件夹获取测试文件,并在测试中使用此文件发送请求 谢谢!
更多关于Golang测试文件上传功能的方法与实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
到目前为止你写了什么?我不认为你的提问方式正确:首先你应该告诉我们你尝试了什么,然后我们才会告诉你接下来该尝试什么。我们不是来这里为你写代码的。
举个例子,你可以实现自己的(模拟)http.ResponseWriter 来测试是否获取到了正确的数据。这样你就不需要写入磁盘,而单元测试通常也不应该做这种事情。
更多关于Golang测试文件上传功能的方法与实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
以下是针对文件上传处理程序的测试实现,使用Go标准库的httptest包和测试文件:
package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
)
func TestUploadFile(t *testing.T) {
// 创建测试文件
tmpDir := "tmp"
testFileName := "testfile.txt"
testFilePath := filepath.Join(tmpDir, testFileName)
// 确保tmp目录存在
if err := os.MkdirAll(tmpDir, 0755); err != nil {
t.Fatalf("Failed to create tmp directory: %v", err)
}
// 创建测试文件内容
testContent := "This is a test file content"
if err := os.WriteFile(testFilePath, []byte(testContent), 0644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
defer os.RemoveAll(tmpDir)
// 打开测试文件
file, err := os.Open(testFilePath)
if err != nil {
t.Fatalf("Failed to open test file: %v", err)
}
defer file.Close()
// 创建multipart表单
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("uploadFile", testFileName)
if err != nil {
t.Fatalf("Failed to create form file: %v", err)
}
// 复制文件内容到表单
_, err = io.Copy(part, file)
if err != nil {
t.Fatalf("Failed to copy file content: %v", err)
}
writer.Close()
// 创建测试请求
req := httptest.NewRequest("POST", "/upload", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
// 创建响应记录器
rr := httptest.NewRecorder()
// 调用处理函数
UploadFile(rr, req)
// 检查响应状态码
if status := rr.Code; status != http.StatusOK {
t.Errorf("Handler returned wrong status code: got %v want %v", status, http.StatusOK)
}
}
func TestUploadFile_InvalidFile(t *testing.T) {
// 测试无效文件上传
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// 不添加任何文件字段
writer.Close()
req := httptest.NewRequest("POST", "/upload", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
rr := httptest.NewRecorder()
UploadFile(rr, req)
// 应该返回400状态码
if status := rr.Code; status != http.StatusBadRequest {
t.Errorf("Handler returned wrong status code: got %v want %v", status, http.StatusBadRequest)
}
expected := "Invalid file to upload"
if rr.Body.String() != expected {
t.Errorf("Handler returned unexpected body: got %v want %v", rr.Body.String(), expected)
}
}
func TestUploadFile_ReadError(t *testing.T) {
// 模拟读取错误的情况
tmpDir := "tmp"
testFileName := "testfile.txt"
testFilePath := filepath.Join(tmpDir, testFileName)
os.MkdirAll(tmpDir, 0755)
// 创建空文件
os.WriteFile(testFilePath, []byte{}, 0644)
defer os.RemoveAll(tmpDir)
file, _ := os.Open(testFilePath)
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("uploadFile", testFileName)
// 这里可以模拟读取错误,但实际测试中文件为空应该能正常处理
io.Copy(part, file)
writer.Close()
req := httptest.NewRequest("POST", "/upload", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
rr := httptest.NewRecorder()
UploadFile(rr, req)
// 检查响应
if rr.Code != http.StatusBadRequest {
t.Errorf("Expected status %v, got %v", http.StatusBadRequest, rr.Code)
}
}
注意:你的原始处理函数需要返回成功状态码才能通过测试。建议在处理成功时添加:
// 在处理函数成功时添加
w.WriteHeader(http.StatusOK)
io.WriteString(w, "File uploaded successfully")
测试文件结构:
project/
├── main.go
├── tmp/
│ └── testfile.txt
└── main_test.go
运行测试:
go test -v

