Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing reference from Global Setup #18

Closed
sporto opened this issue Nov 22, 2013 · 6 comments
Closed

Passing reference from Global Setup #18

sporto opened this issue Nov 22, 2013 · 6 comments

Comments

@sporto
Copy link

sporto commented Nov 22, 2013

In my global setup I get a reference to a db session.

func TestBooks(t *testing.T) {
    RegisterFailHandler(Fail)

    //Code to set up your infrastructure
    dbSession := ...

    RunSpecs(t, "Books Suite")
}

Then I my test I will like to use this reference.

It("does something", func() {
    foo, err := service.Run(dbSession)
    ...
})

How can I do this?

Maybe Ginkgo needs a beforeAll block to do this?

@onsi
Copy link
Owner

onsi commented Nov 22, 2013

I ran into this myself and also thought "does Ginkgo need a beforeAll block"? Then I realized:

func TestBooks(t *testing.T) {
    RegisterFailHandler(Fail)

    //BEFORE ALL
    RunSpecs(t, "Books Suite")
    //AFTER ALL
}

Here's how I share global state:

var dbSession *DBSession

func TestBooks(t *testing.T) {
    RegisterFailHandler(Fail)

    dbSession = DBSession.New(...)
    err := dbSession.Connect()
    Ω(err).ShouldNot(HaveOccured())
    RunSpecs(t, "Books Suite")
    dbSession.Disconnect()
}

Now your Its have access to the global dbSession and, because Ginkgo will only call your Befores and Its during RunSpecs you can trust that the dbSession is initialized.

There's one more trick here. If you want to reset the DB between each test you can do this in your bootstrap file:

var dbSession *DBSession

func TestBooks(t *testing.T) {
    RegisterFailHandler(Fail)

    dbSession = DBSession.New(...)
    err := dbSession.Connect()
    Ω(err).ShouldNot(HaveOccured())
    RunSpecs(t, "Books Suite")
    dbSession.Disconnect()
}

var _ = BeforeEach(func() {
    err := dbSession.Reset()
    Ω(err).ShouldNot(HaveOccured())
})

This is a top-level BeforeEach that will run before every test.

One last pattern: when I have a lot of infrastructure for a test suite (e.g. an integration test suite that manages multiple external processes) I wrap all that stuff into a separate mothership/provider object and initialize/reset that object in the boostrap but then pull things off of that object throughout my various tests. This keeps the bootstrap file small and centralizes all the infrastructure management to a separate object/package (which can now be shared among tests).

@onsi onsi closed this as completed Nov 22, 2013
@onsi
Copy link
Owner

onsi commented Nov 22, 2013

oops.. didn't mean to close the issue -- i'll let you do that @sporto if you think the approach I outlined above is sufficient.

@onsi onsi reopened this Nov 22, 2013
@sporto
Copy link
Author

sporto commented Nov 23, 2013

Cool this works, thanks.

There is a subtle mistake I ran into and I thought this was not working (just writing it here for future reference):

var dbSession *DBSession

func TestBooks(t *testing.T) {
        RegisterFailHandler(Fail)

    dbSession, err := DBSession.New(...)
    if err != nil {
        ...
    }
    RunSpecs(t, "Books Suite")
}

In this case I shadowed the variable dbSession without thinking about it because I needed to get err in the same line, so then dbSession was nil in my tests.

@sporto sporto closed this as completed Nov 23, 2013
@onsi
Copy link
Owner

onsi commented Nov 23, 2013

Yep... I think I run into this one three times a day ;)

Sent from my iPad

On Nov 22, 2013, at 5:52 PM, Sebastian Porto notifications@github.com wrote:

Cool this works, thanks.

There is a subtle mistake I ran into and I thought this was not working (just writing it here for future reference):

var dbSession *DBSession

func TestBooks(t *testing.T) {
RegisterFailHandler(Fail)

dbSession, err := DBSession.New(...)
if err != nil {
    ...
}
RunSpecs(t, "Books Suite")

}
In this case I shadowed the variable dbSession without thinking about it because I needed to get err in the same line, so then dbSession was nil in my tests.


Reply to this email directly or view it on GitHub.

@tzvatot
Copy link

tzvatot commented Feb 18, 2019

I would really like to have beforeAll() that will run once before all the It it cover.
The reason is that you sometime group together several specs and they all can share a common state, but I don't want that state to be global to the suite: it's not serving all the specs.

@williammartin
Copy link
Sponsor Collaborator

Please add your thoughts to #70 @tzvatot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants