FAQ
I know I'm bringing up an old topic, but is there anything wrong with Trung
Pham's approach to defining these functions as vars and redefining them at
test time?
On Wednesday, August 22, 2012 6:04:15 AM UTC-7, John Beisley wrote:

You could always do something like: http://play.golang.org/p/y3RqWYVtpt

It solves the problem without a global, but does mean splitting your
function into a public function (that simply
wraps the call with normal implementation), and a private function
that uses the implementation it is given.
On 21 August 2012 17:39, <rock...@google.com <javascript:>> wrote:
But then anyone in the world using your package could re-define
MyFunction
to be whatever they want. This could be a major problem for
encapsulation
and for the integrity of your package. Alternatively, you could have
MyFunction delegate to myFunction and make myFunction a var. Then you can
still use your scheme for testing, and still prevent the rest of the world
from changing your MyFunction. But personally, I never liked redefining
functions and then switching them back because what happens if your test
harness is multi-threaded?

On Thursday, July 5, 2012 12:41:16 PM UTC-7, Trung Pham wrote:

I figured out how to do what I want in Go. Basically, turn everything
into
a var, and redefine it in my unit test, then restore it afterward.

In myapp.go file

package myapp

var MyFunction = func () int{
//do something very complicated.
}

instead of
func MyFunction() int{
//do something very complicated
}


And in my unit test

import "myapp"

func TestSomething(t testing.T){

oldMyFunction = myapp.MyFunction
myapp.MyFunction = func() int{
//simply return 1;
}

//call something that call myapp.MyFunction


//restore myapp.MyFunction after my test is done

myapp.MyFunction = oldMyFunction

}



It's ugly but it serves my purpose. However, I can do this on packages
that I wrote because other packages do not define their function as
variables.



On Saturday, June 23, 2012 7:32:52 PM UTC-7, sdeg...@8thlight.comwrote:
No, it's not possible because OCMock makes use of ObjC's
metaprogramming
abilities to create methods on an object at run-time. There may be
some
other technique to simplify the redundancy in implementation which
we'll
keep seeing, and the community seems to be working on this over time.
But
for now the solution is to write your own mocks and make careful use
of
interfaces. This is the only downside to having no meta-programming,
but
it's totally worth it, because in every other situation, magic sucks.

-Steven

On Saturday, June 23, 2012 7:32:37 PM UTC-5, Trung Pham wrote:

Mocking seems to be pretty easy in Objective-C(also compiled) using
this
library, http://ocmock.org/.

Can such library be ported to Go?

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 golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Roger peppe at Sep 19, 2013 at 7:48 pm

    On 19 September 2013 20:32, Isaac Mosquera wrote:
    I know I'm bringing up an old topic, but is there anything wrong with Trung
    Pham's approach to defining these functions as vars and redefining them at
    test time?
    We use that approach sometimes.

    The convention goes something like this:

    in the code:

    package mypkg

    // The following are variables so that they can be
    // changed by tests.
    var (
         someMethod = (*somepkg.SomeType).Method
         someFunc = somepkg.SomeFunc
    )

    func myFunc() {
         someMethod(obj, args)
         someFunc(args)
    }

    in export_test.go:

    package mypkg
    var (
         SomeMethod = &someMethod
         SomeFunc = &someFunc
    )

    in some_test.go:

    package mypg_test

    func TestSomething(t *testing.T) {
         defer testinghelpers.Patch(mypkg.SomeMethod, func(*somepkg.SomeType, args) {
             mock method
         }).Restore()
         defer testinghelpers.Patch(mypkg.SomeFunc, func(args) {
            mock function
         }).Restore()
         actual test
    }

    where testinghelpers.Patch is defined like this:
    http://play.golang.org/p/oLF1XnRX3C
    and testinghelpers has a shorter package name :-)

    It's good to avoid this approach where possible, but sometimes
    it's difficult to get good test coverage without it, particular for
    testing error paths.

    --
    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 golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Julian Phillips at Sep 19, 2013 at 9:44 pm

    On 19/09/2013 20:48, roger peppe wrote:
    On 19 September 2013 20:32, Isaac Mosquera wrote:
    I know I'm bringing up an old topic, but is there anything wrong
    with Trung
    Pham's approach to defining these functions as vars and redefining
    them at
    test time?
    We use that approach sometimes.

    The convention goes something like this:

    in the code:

    package mypkg

    // The following are variables so that they can be
    // changed by tests.
    var (
    someMethod = (*somepkg.SomeType).Method
    someFunc = somepkg.SomeFunc
    )

    func myFunc() {
    someMethod(obj, args)
    someFunc(args)
    }

    in export_test.go:

    package mypkg
    var (
    SomeMethod = &someMethod
    SomeFunc = &someFunc
    )

    in some_test.go:

    package mypg_test

    func TestSomething(t *testing.T) {
    defer testinghelpers.Patch(mypkg.SomeMethod,
    func(*somepkg.SomeType, args) {
    mock method
    }).Restore()
    defer testinghelpers.Patch(mypkg.SomeFunc, func(args) {
    mock function
    }).Restore()
    actual test
    }

    where testinghelpers.Patch is defined like this:
    http://play.golang.org/p/oLF1XnRX3C
    and testinghelpers has a shorter package name :-)

    It's good to avoid this approach where possible, but sometimes
    it's difficult to get good test coverage without it, particular for
    testing error paths.
    I recently wrote a tool (github.com/qur/withmock) that will mock out
    packages automatically for getting into those icky corners when testing
    ...

    So you might have code:

    package mypkg

    import "somepkg"

    func MyFunc() {
          somepkg.SomeFunction()
    }

    with test code:

    package mypkg_test

    import (
          "somepkg" // mock
          "code.google.com/p/gomock"
    )

    func TestMyFunc(t *testing.T) {
          ctrl := gomock.NewController()
          defer crtl.Finish()
          somepkg.MOCK().SetController(ctrl)
          somepkg.EXPECT().SomeFunction()
          MyFunc()
    }

    --
    Julian

    --
    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 golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Isaac Mosquera at Sep 19, 2013 at 9:51 pm
    Julian/rog - thanks for the libraries & code. This is exactly what i'm
    looking for. Thanks!
    On Thursday, September 19, 2013 2:44:10 PM UTC-7, Julian Phillips wrote:
    On 19/09/2013 20:48, roger peppe wrote:
    On 19 September 2013 20:32, Isaac Mosquera <is...@sharethis.com<javascript:>>
    wrote:
    I know I'm bringing up an old topic, but is there anything wrong
    with Trung
    Pham's approach to defining these functions as vars and redefining
    them at
    test time?
    We use that approach sometimes.

    The convention goes something like this:

    in the code:

    package mypkg

    // The following are variables so that they can be
    // changed by tests.
    var (
    someMethod = (*somepkg.SomeType).Method
    someFunc = somepkg.SomeFunc
    )

    func myFunc() {
    someMethod(obj, args)
    someFunc(args)
    }

    in export_test.go:

    package mypkg
    var (
    SomeMethod = &someMethod
    SomeFunc = &someFunc
    )

    in some_test.go:

    package mypg_test

    func TestSomething(t *testing.T) {
    defer testinghelpers.Patch(mypkg.SomeMethod,
    func(*somepkg.SomeType, args) {
    mock method
    }).Restore()
    defer testinghelpers.Patch(mypkg.SomeFunc, func(args) {
    mock function
    }).Restore()
    actual test
    }

    where testinghelpers.Patch is defined like this:
    http://play.golang.org/p/oLF1XnRX3C
    and testinghelpers has a shorter package name :-)

    It's good to avoid this approach where possible, but sometimes
    it's difficult to get good test coverage without it, particular for
    testing error paths.
    I recently wrote a tool (github.com/qur/withmock) that will mock out
    packages automatically for getting into those icky corners when testing
    ...

    So you might have code:

    package mypkg

    import "somepkg"

    func MyFunc() {
    somepkg.SomeFunction()
    }

    with test code:

    package mypkg_test

    import (
    "somepkg" // mock
    "code.google.com/p/gomock"
    )

    func TestMyFunc(t *testing.T) {
    ctrl := gomock.NewController()
    defer crtl.Finish()
    somepkg.MOCK().SetController(ctrl)
    somepkg.EXPECT().SomeFunction()
    MyFunc()
    }

    --
    Julian
    --
    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 golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Nathan Youngman at Sep 20, 2013 at 6:59 am
    There's this article on httptest:
    https://willnorris.com/

    Here's an article on using the lambda approach:
    http://openmymind.net/Dependency-Injection-In-Go/

    Though so far I'm just using interfaces for doubles/fakes. I haven't gotten into mocking/expectations in Go yet.

    --
    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 golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Michael Whatcott at Sep 20, 2013 at 1:00 pm
    Hand-rolled mocks can be effective in many cases:

    https://sites.google.com/site/unclebobconsultingllc/home/articles/manual-mocking---resisting-the-invasion-of-dots-and-parenthesis
    http://blog.8thlight.com/josh-cheek/2011/11/28/three-reasons-to-roll-your-own-mocks.html
    On Monday, May 28, 2012 1:43:17 PM UTC-6, Trung Pham wrote:

    How do I mock/stub a method in my unit test in order to remove dependency?

    This is relative simple to do in a dynamic language like ruby or
    javascript. Since it lets you redefine any method on the fly, and restore
    it afterward.

    Mocking is an extremely useful feature when it comes to unit testing. Say
    if your code makes an externally http request to get something. In your
    unit test, you would not want to actually make the http call because it's
    expensive, unreliable, and you have no way of controlling what you will
    get. Rather you would mock the http response to be some fixed result, and
    test that given outcome.

    For example, in ruby I can do something like this.

    HTTP.should_receive(:get).and_return("Hello world")

    HTTP.get("http://example.com").should == "Hello world"

    Please let me know what library or tool you use for mocking method in Go.

    Thank you.
    --
    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 golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedSep 19, '13 at 7:33p
activeSep 20, '13 at 1:00p
posts6
users5
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase