duanji9378 2013-11-04 07:04
浏览 75
已采纳

单元测试golang处理程序

Here's a handler I wrote to retrieve a document from mongodb.
If the document is found, we will load and render the template accordingly. If it fails, it will redirect to 404.

func EventNextHandler(w http.ResponseWriter, r *http.Request) {

    search := bson.M{"data.start_time": bson.M{"$gte": time.Now()}}
    sort := "data.start_time"
    var result *Event
    err := db.Find(&Event{}, search).Sort(sort).One(&result)
    if err != nil && err != mgo.ErrNotFound {
        panic(err)
    }
    if err == mgo.ErrNotFound {
        fmt.Println("No such object in db. Redirect")
        http.Redirect(w, r, "/404/", http.StatusFound)
        return
    }

    // TODO: 
    // This is the absolute path parsing of template files so tests will pass
    // Code can be better organized
    var eventnext = template.Must(template.ParseFiles(
        path.Join(conf.Config.ProjectRoot, "templates/_base.html"),
        path.Join(conf.Config.ProjectRoot, "templates/event_next.html"),
    ))

    type templateData struct {
        Context *conf.Context
        E *Event
    }

    data := templateData{conf.DefaultContext(conf.Config), result}

    eventnext.Execute(w, data)

}

Manually trying this out, everything works great.

However, I can't seem to get this to pass my unit tests. In a corresponding test file, this is my test code to attempt to load my EventNextHandler.

func TestEventNextHandler(t *testing.T) {

    // integration test on http requests to EventNextHandler

    request, _ := http.NewRequest("GET", "/events/next/", nil)
    response := httptest.NewRecorder()

    EventNextHandler(response, request)

    if response.Code != http.StatusOK {
        t.Fatalf("Non-expected status code%v:
\tbody: %v", "200", response.Code)
    }

}

The test fails at the line stating EventNextHandler(response, request).

And in my error message, it refers to the line err := db.Find(&Event{}, search).Sort(sort).One(&result) in my handler code.

Complete error message here:-

=== RUN TestEventNextHandler
--- FAIL: TestEventNextHandler (0.00 seconds)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x8 pc=0x113eb8]

goroutine 4 [running]:
testing.func·004()
    /usr/local/go/src/pkg/testing/testing.go:348 +0xcd
hp/db.Cursor(0xc2000c3cf0, 0xc2000fb1c0, 0x252d00)
    /Users/calvin/gopath/src/hp/db/db.go:57 +0x98
hp/db.Find(0xc2000c3cf0, 0xc2000fb1c0, 0x252d00, 0xc2000e55c0, 0x252d00, ...)
    /Users/calvin/gopath/src/hp/db/db.go:61 +0x2f
hp/event.EventNextHandler(0xc2000e5580, 0xc2000a16a0, 0xc2000c5680)
    /Users/calvin/gopath/src/hp/event/controllers.go:106 +0x1da
hp/event.TestEventNextHandler(0xc2000d5240)
    /Users/calvin/gopath/src/hp/event/controllers_test.go:16 +0x107
testing.tRunner(0xc2000d5240, 0x526fe0)
    /usr/local/go/src/pkg/testing/testing.go:353 +0x8a
created by testing.RunTests
    /usr/local/go/src/pkg/testing/testing.go:433 +0x86b

goroutine 1 [chan receive]:
testing.RunTests(0x3bdff0, 0x526fe0, 0x1, 0x1, 0x1, ...)
    /usr/local/go/src/pkg/testing/testing.go:434 +0x88e
testing.Main(0x3bdff0, 0x526fe0, 0x1, 0x1, 0x532580, ...)
    /usr/local/go/src/pkg/testing/testing.go:365 +0x8a
main.main()
    hp/event/_test/_testmain.go:43 +0x9a

What is the correct way to write my tests? To take into account the situation where nothing gets retrieved from mongodb and apply an assertion to verify that, thus writing a validated test.

  • 写回答

1条回答 默认 最新

  • dongwei2882 2013-11-04 12:37
    关注

    It appears that I did not initialize db in my test. Much like a "setup" step similar to all other languages' unit testing framework.

    I have to ensure that my db package is imported and then implement two lines to Connect to the database and register the indexes.

    func TestEventNextHandler(t *testing.T) {
    
        // set up test database
    
        db.Connect("127.0.0.1", "test_db")
        db.RegisterAllIndexes()
    
        // integration test on http requests to EventNextHandler
    
        request, _ := http.NewRequest("GET", "/events/next/", nil)
        response := httptest.NewRecorder()
    
        EventNextHandler(response, request)
    
        if response.Code != 302 {
            t.Fatalf("Non-expected status code %v:
    \tbody: %v", "200", response.Code)
        }
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算