FAQ
In tests, I often need to stub out some global functions. E.g. a common
example is to stub out "time.Now" or "os.Hostname".

There seem to be 2 main options:

1) Create a Clock interface, and an implementation which uses the real
clock in production, but a fake clock in tests.
2) Create a var to refer to the global function, and replace that in tests.
e.g. var timeNow = time.Now

Option 1 is a lot of extra code, and I don't like to use interfaces when
there's only one real implementation used in production code.
Option 2 works, but it's a little ugly as your code no longer uses the
function directly, so you'll see "timeNow()" instead of "time.Now()". This
makes it harder to search code, and it allows for the timeNow var to be
changed in production code, which I never actually want.

It would be great if there was a better solution to this problem. I've
thought of a couple of options:

1) Allow functions to be stubbed only during tests. Func declarations could
be treated as var FuncName = func(...)
The main problem I see with this is that a separate build of the standard
library may need to be used to achieve this.

2) Rewrite code for test builds that will create the variable "var timeNow
= time.Now" and use the variable instead of the real function and allow it
to be stubbed, but only for tests.

I think 2) would work better if a stubbing library (something like gostub
<https://github.com/prashantv/gostub>) was part of "testing" in the
standard library, as then calls to a Stub function could be recognized by
"go test" and replaced to use a var.

It'd be great to hear feedback or other ideas for this problem, thanks.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Matt Harden at Jul 10, 2015 at 7:44 pm
    I believe you can put a build flag on a file to keep it from being included
    for tests. In that file you could have functions that just wrap the stdlib
    functions you need to stub, and have a stubs_test.go that contains the
    stubs. In production the trivial wrapper functions *should* be inlined for
    no real performance hit; I'm not certain of that though.
    On Fri, Jul 10, 2015 at 12:56 PM Prashant V wrote:

    In tests, I often need to stub out some global functions. E.g. a common
    example is to stub out "time.Now" or "os.Hostname".

    There seem to be 2 main options:

    1) Create a Clock interface, and an implementation which uses the real
    clock in production, but a fake clock in tests.
    2) Create a var to refer to the global function, and replace that in
    tests. e.g. var timeNow = time.Now

    Option 1 is a lot of extra code, and I don't like to use interfaces when
    there's only one real implementation used in production code.
    Option 2 works, but it's a little ugly as your code no longer uses the
    function directly, so you'll see "timeNow()" instead of "time.Now()". This
    makes it harder to search code, and it allows for the timeNow var to be
    changed in production code, which I never actually want.

    It would be great if there was a better solution to this problem. I've
    thought of a couple of options:

    1) Allow functions to be stubbed only during tests. Func declarations
    could be treated as var FuncName = func(...)
    The main problem I see with this is that a separate build of the standard
    library may need to be used to achieve this.

    2) Rewrite code for test builds that will create the variable "var timeNow
    = time.Now" and use the variable instead of the real function and allow it
    to be stubbed, but only for tests.

    I think 2) would work better if a stubbing library (something like gostub
    <https://github.com/prashantv/gostub>) was part of "testing" in the
    standard library, as then calls to a Stub function could be recognized by
    "go test" and replaced to use a var.

    It'd be great to hear feedback or other ideas for this problem, thanks.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to [email protected].
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
    For more options, visit https://groups.google.com/d/optout.
  • Matt Harden at Jul 10, 2015 at 7:45 pm
    You could also check to see what they do in the Go Playground, where lots
    of stdlib stuff is replaced with stubs.
    On Fri, Jul 10, 2015 at 2:44 PM Matt Harden wrote:

    I believe you can put a build flag on a file to keep it from being
    included for tests. In that file you could have functions that just wrap
    the stdlib functions you need to stub, and have a stubs_test.go that
    contains the stubs. In production the trivial wrapper functions *should* be
    inlined for no real performance hit; I'm not certain of that though.
    On Fri, Jul 10, 2015 at 12:56 PM Prashant V wrote:

    In tests, I often need to stub out some global functions. E.g. a common
    example is to stub out "time.Now" or "os.Hostname".

    There seem to be 2 main options:

    1) Create a Clock interface, and an implementation which uses the real
    clock in production, but a fake clock in tests.
    2) Create a var to refer to the global function, and replace that in
    tests. e.g. var timeNow = time.Now

    Option 1 is a lot of extra code, and I don't like to use interfaces when
    there's only one real implementation used in production code.
    Option 2 works, but it's a little ugly as your code no longer uses the
    function directly, so you'll see "timeNow()" instead of "time.Now()". This
    makes it harder to search code, and it allows for the timeNow var to be
    changed in production code, which I never actually want.

    It would be great if there was a better solution to this problem. I've
    thought of a couple of options:

    1) Allow functions to be stubbed only during tests. Func declarations
    could be treated as var FuncName = func(...)
    The main problem I see with this is that a separate build of the standard
    library may need to be used to achieve this.

    2) Rewrite code for test builds that will create the variable "var
    timeNow = time.Now" and use the variable instead of the real function and
    allow it to be stubbed, but only for tests.

    I think 2) would work better if a stubbing library (something like gostub
    <https://github.com/prashantv/gostub>) was part of "testing" in the
    standard library, as then calls to a Stub function could be recognized by
    "go test" and replaced to use a var.

    It'd be great to hear feedback or other ideas for this problem, thanks.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to [email protected].
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
    For more options, visit https://groups.google.com/d/optout.
  • Prashant Is Here at Jul 10, 2015 at 9:42 pm
    Hi Matt,

    Thanks for the suggestion. However, what I'd like it
      - production code retains function calls to the real libraries. Eg, I want
    to be able to use time.Now and not use timeNow. Build tags involves extra
    boilerplate for every stubbed function which isn't ideal, and uses a
    separate name.
      - I don't want tests to *have* to stub them out - it's yet again more
    code. It also makes it harder to have tests that only need a subset of the
    functions to be stubbed.

    I think the current "var timeNow = time.Now" is a preferable solution to
    build tags, as it's lighter-weight from a developer's perspective, but I'd
    like something nicer.
    On Friday, 10 July 2015 13:46:03 UTC-6, Matt Harden wrote:

    You could also check to see what they do in the Go Playground, where lots
    of stdlib stuff is replaced with stubs.

    On Fri, Jul 10, 2015 at 2:44 PM Matt Harden <[email protected]
    <javascript:>> wrote:
    I believe you can put a build flag on a file to keep it from being
    included for tests. In that file you could have functions that just wrap
    the stdlib functions you need to stub, and have a stubs_test.go that
    contains the stubs. In production the trivial wrapper functions *should* be
    inlined for no real performance hit; I'm not certain of that though.

    On Fri, Jul 10, 2015 at 12:56 PM Prashant V <[email protected]
    <javascript:>> wrote:
    In tests, I often need to stub out some global functions. E.g. a common
    example is to stub out "time.Now" or "os.Hostname".

    There seem to be 2 main options:

    1) Create a Clock interface, and an implementation which uses the real
    clock in production, but a fake clock in tests.
    2) Create a var to refer to the global function, and replace that in
    tests. e.g. var timeNow = time.Now

    Option 1 is a lot of extra code, and I don't like to use interfaces when
    there's only one real implementation used in production code.
    Option 2 works, but it's a little ugly as your code no longer uses the
    function directly, so you'll see "timeNow()" instead of "time.Now()". This
    makes it harder to search code, and it allows for the timeNow var to be
    changed in production code, which I never actually want.

    It would be great if there was a better solution to this problem. I've
    thought of a couple of options:

    1) Allow functions to be stubbed only during tests. Func declarations
    could be treated as var FuncName = func(...)
    The main problem I see with this is that a separate build of the
    standard library may need to be used to achieve this.

    2) Rewrite code for test builds that will create the variable "var
    timeNow = time.Now" and use the variable instead of the real function and
    allow it to be stubbed, but only for tests.

    I think 2) would work better if a stubbing library (something like
    gostub <https://github.com/prashantv/gostub>) was part of "testing" in
    the standard library, as then calls to a Stub function could be recognized
    by "go test" and replaced to use a var.

    It'd be great to hear feedback or other ideas for this problem, thanks.

    --
    You received this message because you are subscribed to the Google
    Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send
    an email to [email protected] <javascript:>.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJul 10, '15 at 5:55p
activeJul 10, '15 at 9:42p
posts4
users2
websitegolang.org

2 users in discussion

Prashant Is Here: 2 posts Matt Harden: 2 posts

People

Translate

site design / logo © 2023 Grokbase