Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 如何为BindJSON设置mock gin.Context_Unit Testing_Go Gin_Go Sqlmock - Fatal编程技术网

Unit testing 如何为BindJSON设置mock gin.Context

Unit testing 如何为BindJSON设置mock gin.Context,unit-testing,go-gin,go-sqlmock,Unit Testing,Go Gin,Go Sqlmock,我正在Go中设置测试 我使用go-sqlmock测试mysql连接。现在我尝试测试mysql插入逻辑。 问题是我需要设置mockgin.Context,它稍后用于BindJSON。 但到目前为止,我无法设置这个gin.Context。 server side: golang db: mysql web framework: gin 道,走 unc PostImageToDBDao(c*gin.Context,db*sql.db){ //由于这种逻辑,我需要用json设置gin.Context

我正在
Go
中设置测试
我使用
go-sqlmock
测试mysql连接。现在我尝试测试mysql插入逻辑。

问题是我需要设置mock
gin.Context
,它稍后用于
BindJSON

但到目前为止,我无法设置这个
gin.Context

server side: golang
db: mysql
web framework: gin
道,走

unc PostImageToDBDao(c*gin.Context,db*sql.db){
//由于这种逻辑,我需要用json设置gin.Context
var imageData util.imageData
c、 BindJSON(&imageData)
对于u,imageName:=范围imageData.IMAGENAMES{
ins,err:=db.Prepare(“插入到图像(文章uuid,图像名称)值(?,)”)
如果错误!=零{
log.Fatal(错误)
}
ins.Exec(imageData.ARTICLEUUID,imageName.NAME)
}
}
道尤考试网

func testpositmagetodbdao(t*testing.t){
db,mock,err:=sqlmock.New()
如果错误!=零{
t、 Fatalf(“打开存根数据库连接时不应出现错误“%s”,err)
}
延迟db.Close()
prep:=mock.ExpectPrepare(“^INSERT-INTO-images*”)
prep.ExpectExec()。
带参数(“bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c”、“b8119536-fad5-4ffa-ab71-2f96cca19697”)。
WillReturnResult(sqlmock.NewResult(1,1))
//尝试使用json post设置上下文
req,:=http.NewRequest(“POST”,“/POST/image/db”,bytes.NewBuffer([]字节(`[{
“articleUUID”:“bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c”,
“图像名称”:“b8119536-fad5-4ffa-ab71-2f96cca19697”,
}]`)))
req.Header.Set(“内容类型”、“应用程序/json”)
var context*gin.context
context=&gin.context{Request:req}
PostImageToDBDao(上下文,db)
如果错误:=mock.ExpectationsWereMet();错误!=nil{
t、 Errorf(“有未实现的预期:%s”,err)
}
}
我希望mock
gin.Context
设置正确,运行
go test-v
时不会出错。
但实际情况是,它会出错。
我想解决此错误并使测试成功。

=== RUN   TestPostImageToDBDao
[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 0 with 400
--- FAIL: TestPostImageToDBDao (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x60 pc=0x15bde75]

goroutine 50 [running]:
testing.tRunner.func1(0xc000234100)
        /usr/local/go/src/testing/testing.go:830 +0x392
panic(0x16918e0, 0x1ce5850)
        /usr/local/go/src/runtime/panic.go:522 +0x1b5
github.com/gin-gonic/gin.(*Context).AbortWithStatus(0xc00026aee8, 0x190)
        /Users/jpskgc/go/pkg/mod/github.com/gin-gonic/gin@v1.4.0/context.go:146 +0x45
github.com/gin-gonic/gin.(*Context).AbortWithError(0xc0000d9ee8, 0x190, 0x1863e00, 0xc0002700a0, 0x1863e00)
        /Users/jpskgc/go/pkg/mod/github.com/gin-gonic/gin@v1.4.0/context.go:162 +0x39
github.com/gin-gonic/gin.(*Context).MustBindWith(0xc00026aee8, 0x16328e0, 0xc00022c180, 0x186e060, 0x1d16588, 0x1e316d0, 0x0)
        /Users/jpskgc/go/pkg/mod/github.com/gin-gonic/gin@v1.4.0/context.go:561 +0x92
github.com/gin-gonic/gin.(*Context).BindJSON(...)
        /Users/jpskgc/go/pkg/mod/github.com/gin-gonic/gin@v1.4.0/context.go:528
article/api/dao.PostImageToDBDao(0xc00026aee8, 0xc000276000)
        /Users/jpskgc/article/api/dao/dao.go:54 +0x87
article/api/dao.TestPostImageToDBDao(0xc000234100)
        /Users/jpskgc/article/api/dao/dao_test.go:204 +0x4b6
testing.tRunner(0xc000234100, 0x17897e0)
        /usr/local/go/src/testing/testing.go:865 +0xc0
created by testing.(*T).Run
        /usr/local/go/src/testing/testing.go:916 +0x35a
exit status 2
FAIL    article/api/dao 0.032s

首先,您必须实例化一个测试
*gin.Context
,并确保其
*http.Request
为非nil:

    w := httptest.NewRecorder()
    c, _ := gin.CreateTestContext(w) 

    c.Request = &http.Request{
        Header: make(http.Header),
    }
然后,您可以通过以下方式模拟POST json主体:

func MockJsonPost(c*gin.Context/*测试上下文*/,内容接口{}){
c、 Request.Method=“POST”//或PUT
c、 Request.Header.Set(“内容类型”、“应用程序/json”)
jsonbytes,err:=json.Marshal(jsonMap)
如果错误!=零{
恐慌(错误)
}
//请求正文必须是io.ReadCloser
//虽然字节缓冲区没有实现io.Closer,
//所以你把它包在一个不可操作的闭合器里
c、 Request.Body=io.nocloser(bytes.NewBuffer(jsonbytes))
}
其中,函数参数
content interface{}
是可以编组为JSON的任何东西,因此在大多数情况下,结构具有适当的
JSON
标记,或
map[string]interface{}

用法示例:

func TestMyHandler(t *testing.T) {
    w := httptest.NewRecorder()
    ctx, _ := gin.CreateTestContext(w) 

    ctx.Request = &http.Request{
        Header: make(http.Header),
    }


    MockJsonPost(ctx, map[string]interface{}{"foo": "bar"})
    
    MyHandler(ctx)
    assert.EqualValues(t, http.StatusOK, w.Code)
} 
试试这个: