【问题标题】:Running Ginkgo test suite (BeforeSuite setup before any spec is ran在运行任何规范之前运行 Ginkgo 测试套件(BeforeSuite 设置
【发布时间】:2016-03-24 14:42:53
【问题描述】:

我正在使用 Ginkgo(和 Gomega)包对 Go(lang) Rest API 进行单元测试。

我需要使用全局设置,这应该可以通过定义来实现

var _ = BeforeSuite(func() {...})

然后每个规范(具体的<file>_test.go)应该在这个全局设置之后运行。不幸的是,我无法做到这一点......

我的套件文件名是handlers_suite_test.go,我的第一个测试规范名称是cartContentsHandler_test.go。在我看来,Ginkgo 按字母顺序运行测试文件,使 cartContentsHandler_test.go 运行 before handlers_suite_test.go。我在两个文件中都放了一些log() 调用,不幸的是他们只是证实了我的发现......

这真是令人不快的情况,因为我根本无法让我的测试运行...我需要确保在所有规范之前设置并运行httptest.Server 和数据库池连接。

您知道如何使suite_test 作为测试规范之前的第一个文件运行吗?(我已经尝试将套件文件命名为_suite_test.go,但在这种情况下看起来套件根本没有执行)。

我的handlers_suite_test.go

package handlers_test

import (
    "<PROJ>/config"
    "<PROJ>/lib"
    "<PROJ>/router"
    "github.com/gorilla/mux"
    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"

    "log"
    "net/http/httptest"
    "os"
    "testing"
)

var r *mux.Router
var s *httptest.Server
var serverURL string

func TestHandlers(t *testing.T) {
    RegisterFailHandler(Fail)
    RunSpecs(t, "Caracal Handlers Suite")
}

var _ = BeforeSuite(func() {
    r = router.NewRouter()
    s = httptest.NewServer(r)
    Expect(len(s.URL)).To(BeNumerically(">", 0))
    serverURL = s.URL
    log.Print("###" + serverURL + "###\n\n") // ==> THIS PRINTS MUCH LATER AFTER log.Print() in cartContentsHandler_test.go

    cwd, _ := os.Getwd()
    cfg := config.ReadCfg(cwd + "/../config/config.json").DB
    lib.DB = lib.InitDB(cfg)
    err := lib.DB.Ping()
    Expect(err).NotTo(HaveOccurred())
})

var _ = AfterSuite(func() {
    //  lib.DB.Close() // ==> this was running into Panic...
    s.Close()
})

我的cartContensHandler_test.go

包 handlers_test

import (
    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"

    "log"
    "net/http"
    "strings"
)

var _ = Describe("Handlers/CartContentsHandler", func() {
    Describe("Retrieves all available cart content types", func() {
        Context("No query string parameters", func() {
            var rdr *strings.Reader
            var req *http.Request
            var res *http.Response
            var err error
            var url = serverURL + "/cart-contents"

            log.Print(url)

            It("Makes a GET request", func() {
                rdr = strings.NewReader("")
                req, err = http.NewRequest("GET", url, rdr)
                Expect(err).NotTo(HaveOccurred())
            })

            It("retrieves a response", func() {
                res, err = http.DefaultClient.Do(req)
                Expect(err).NotTo(HaveOccurred())
            })

            It("Returns HTTP 200 OK", func() {
                Expect(res.StatusCode).To(BeNumerically("==", http.StatusOK)) // ==> NOW THIS RETURNS 404 as request is to URL without server part
            })
        })
    })
})

根目录下,我以这种方式运行测试:

ginkgo handlers -cover --v

【问题讨论】:

  • 如果你在 cartContensHandler_test.go 的 It 函数中加入 log.Print 会发生什么?
  • 嗯,所以在It 中添加新的log.Print() 输出真的是在BeforeSuite 中的打印之后!我会将规范“设置”代码移动到It 并尝试一下!

标签: unit-testing go ginkgo


【解决方案1】:

发生的情况是BeforeSuite 注册了一个将在测试套件之前执行的函数,而It 注册了一个将成为测试套件一部分的测试函数。对DescribeContext 的回调会立即执行。所以你必须把所有依赖BeforeSuite的东西都放到It中。

【讨论】:

  • 你是我的英雄!谢谢!!!所以最后我可以用一个全局设置运行一个包的测试!!!万岁!!!并且使用 Ginkgo 和 Gomega,单元测试看起来也像我在 PHP 或 JS 世界中习惯的那样:-)
【解决方案2】:

为保证BeforeSuite 将在Describe 块的本地设置之前运行必要的全局设置,您应该使用BeforeEach

在您的套房中:

var serverURL string

var _ = BeforeSuite(func() {
    r = router.NewRouter()
    s = httptest.NewServer(r)
    serverURL = s.URL
})

在测试中:

var _ = Describe("Handlers/CartContentsHandler", func() {
  var url url.URL

  BeforeEach(func() {
    url = serverURL + "/cart-contents"
  })

  It("Makes a GET request", func() {
    # ....
  })
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2017-05-02
    • 2018-08-23
    • 2014-11-24
    相关资源
    最近更新 更多