0

I'm testing a function which called another function in Go. And here's what I have

package b

type b struct {...}

func (b *b) functionB(){...}
package a

import "b"

type a struct {...}

func (a *a) functionA() {
    b := b{...}
    b.functionB()
    ...
}

I want to modify the function declaration in b like this:

package b

type b struct {...}

var functionB = b.FuncInB

func (b *b) FuncInB(){...}

so that I can mock the return of functionB in a. However, I got error message in a that says b.functionB is undefined because it should be the function of b object. How can I make this work?

mbuechmann
  • 5,413
  • 5
  • 27
  • 40
cainam
  • 55
  • 1
  • 5
  • You should redesign and stop mocking. You should test package b and assume it is working correctly while testing package a and just call methods of b. Mocking is a bad technique, especially in Go. – Volker Nov 19 '19 at 08:24
  • @Volker I'm creating unit testing for my function and need to do this. I see another post about mocking function like this https://stackoverflow.com/questions/19167970/mock-functions-in-go – cainam Nov 19 '19 at 08:31
  • It is not possible to call `b.functionB`, whether it's a function or a method, from `a` because it is *not* [exported](https://golang.org/ref/spec#Exported_identifiers). – mkopriva Nov 19 '19 at 08:44
  • "[I] need to do this". That's why I recommend to redesign because you should not do this. – Volker Nov 19 '19 at 09:07

1 Answers1

0

If you want to use a definition of one package in another package you have to export it. This is done by letting the definition start with a capital letter. Your type should be defined like this:

type B struct {...}

You cannot access a function via its type. This line

var functionB = b.FuncInB

will not work, as you can refer to the function only from an existing struct. You shoule remove this line and call it differently (see below).

Your package a has now two minor issues. When you want to use struct B from package b you have to either refer to it like this b.B

import "b"

b.B{...}

or make a dot import for package b:

import . "b"

B{...}

The last thing is, that you shadow the package name when assigning a variable with the same name as the package. In that, you should use a different variable name:

func (a *a) functionA() {
    myB := b{...}
    myB.FunctionB()
    ...
}

So in the end, your packages should look like this:

package b

type B struct {
    // ...
}

func (b *B) FuncInB() {
    // ...
}
package a

import "b"

type a struct {
    // ...
}

func (a *a) functionA () {
    myB := B {
        // ...
    }
    myB.functionB()
    // ...
}
mbuechmann
  • 5,413
  • 5
  • 27
  • 40
  • thank you for your reply but my problem is about the declaration using var in `b` – cainam Nov 19 '19 at 08:35
  • Your are welcome. It is difficult to answer, because you state your problem in a very abstract way. If you could provide more details of what you actually want to achieve, it would be easier to answer. – mbuechmann Nov 19 '19 at 08:38