Mocking struct argument - go

FULL DISCLOSURE: This is probably really dumb, but I'm new to Go and haven't used statically-typed languages in years.
I have a function that looks like this:
func Foo(bar *bar.BarStruct) {
// do stuff with bar
}
In this example, bar is a third-party package and *bar.BarStruct is a pointer to a struct.
I would like to write a test for the Foo function while stubbing out bar.BarStruct struct. How would I stub out *bar.BarStruct?
In JavaScript for example, I would just do something like this
test('does a Foo', () => {
const mockBarStruct = {
someProp: 123
}
Foo(mockBarStruct)
// rest of test
})
What's the equivalent way to stub a struct in Go?

If you had Foo take an interface instead of a struct pointer, the in tested you could pass a mock or fake struct that implements that interface.
There are some mocking libraries but because Golang doesn’t allow runtime type writing, they run compile-time and output code.
Hope that helps!

Related

How to initialize map without code duplication?

I have a struct type named as game as follows:
type game struct {
commands map[string]*command
// ...
}
And I want to initialize a map in a struct of this type in the init function. I do it like this
func (game *game) init() {
game.commands = make(map[string]*command)
// ...
}
As I think, there is some code duplication. It would be neat if I could declare the type (map[string]*command) only once. Is there a way to do that? I tried to use reflect but it doesn't seem to work because make builtin takes a type and not a value.
If you are worried that repeating map[string]*command two times is duplication, you can define a new type from it.
type commandsMap map[string]*command
type game struct {
commands commandsMap
// ...
}
func (game *game) init() {
game.commands = make(commandsMap)
// ...
}
There is not a code duplication here. Code duplication is when you have multiple points in your code that does the same thing.
That being said, you can leave your code like it is or you can use a Constructor, which has the benefit of restricting this initialization where you type is and is also a cleaner approach imho.
type game struct {
commands map[string]*command
}
func game() *game {
return &game{commands: make(map[string]*command)}
}
That way, when you need a game object, you can just do
gameObject := game()
and then use the map methods as you normally would (or you can also make a utility method just for that)

how to use function of unexported struct [duplicate]

This question already has an answer here:
Is there a way to create a function using unexported type as parameter in Golang?
(1 answer)
Closed 3 months ago.
I have a package where I have unexported struct and exported New function to create it and exported function that runs on this struct (as advised for example here: Return an unexported type from a function).
If I run the function in the same place the New is called I can run the package function but I am unable to send this entity to another function.
what is the best way to achieve this behavior without the need to have all my code in one function
this for example works:
client := package.New()
client.Foo()
but this cannot work:
client := package.New()
hello(client)
func hello(client interface{}) {
client.Foo()
}
What your hello function essentially needs is something that has a Foo function. That's why go has interfaces. There's nothing wrong with returning an unexported type (in fact, it's common and often the right thing to do). What I'd do is this:
package foobar
// whatever thing that has a Foo function
type FClient interface {
Foo()
}
func Hello(client FClient) {
client.Foo() // will work
}
The reason why you'd do it like this is to be able to unit-test this code:
package foobar_test
import (
"testing"
)
type testFC struct {
callCount uint64
}
// implement interface
func (t testFC) Foo() {
testFC.callCount++
}
func TestHello(t *testing.T) {
client := testFC{}
Hello(client)
if client.callCount != 1 {
t.Fail("dependency not called")
}
}
Of course, for more complex dependencies you'd use tools like mockgen or stuff like that, but you get the idea. By definition, a UNIT test focuses on a single UNIT of code. The last thing you'd need to do to test a package unit is to instantiate a type from another package. You should be able to mock everything your code depends on. The best way to do so is interfaces.

Explain go interface definition in go wiki

I understand a bit a go and to certain extend understand interface as well(like how I do ducktyping in ruby)
But reading the interface definition https://github.com/golang/go/wiki/CodeReviewComments
I'm clueless what is trying to convey.
1st: I did not understood the comment.
Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values.
2nd: I do not understand this
Do not define interfaces on the implementor side of an API "for mocking"; instead, design the API so that it can be tested using the public API of the real implementation.
3rd: I do not understand the example
Do not define interfaces before they are used: without a realistic example of usage, it is too difficult to see whether an interface is even necessary, let alone what methods it ought to contain.
package consumer // consumer.go
type Thinger interface { Thing() bool }
func Foo(t Thinger) string { ..... }
package consumer // consumer_test.go
type fakeThinger struct{ … }
func (t fakeThinger) Thing() bool { … }
if Foo(fakeThinger{…}) == "x" { ... }
// DO NOT DO IT!!!
package producer
type Thinger interface { Thing() bool }
type defaultThinger struct{ … }
func (t defaultThinger) Thing() bool { … }
func NewThinger() Thinger { return defaultThinger{ … } }
package producer
type Thinger struct{ … }
func (t Thinger) Thing() bool { … }
func NewThinger() Thinger { return Thinger{ … } }
Can someone explain in plain and easier word the 3 things above.
Forget analogies with other languages for the moment. Think of an interface like a contract - a set of requirements for the function that uses it.
Say I define a function MakeNoise which needs to know the sound of the thing passed in, but otherwise doesn't care about it. Code below is all together, but imagine this in two separate packages - one for concrete types and one for MakeNoise.
The MakeNoise function could take a specific type, but this limits it somewhat, might make testing harder etc, so often you might want it instead to define what it needs the type to do - in this case it just needs something with a Sound() method to call, other than that it doesn't care.
Now on the Cat/Dog side, you might not care about MakeNoise, or even know about it yet, your animals should be defined separately and not care about any interfaces they conform with - those interfaces might not even have been written yet.
So the Wiki is just saying that whoever writes MakeNoise should care about what it requires and put that in an interface, but whoever writes Cat/Dog should not care, and the interface should sit with MakeNoise, not with Cat/Dog. This means later someone might come and write a Giraffe in another package, and it can still be used with MakeNoise.
The interface is a requirement, not a promise.
https://play.golang.org/p/4r1wiXokKMb
// Here are some types which share one function.
// They might have other functions too
package main
type Cat struct {}
func (d Cat) Sound() string {
return "miao"
}
type Dog struct {}
func (d Dog) Sound() string {
return "woof"
}
func main() {
cat := Cat{}
dog := Dog{}
MakeNoise(cat)
MakeNoise(dog)
}
// Sounder is the requirement for MakeNoise, so it lives with it.
// perhaps in a package together which knows nothing of cats and dogs.
type Sounder interface {
Sound() string
}
// MakeNoise prints the sound of the thing
// it only cares the thing makes a Sound
func MakeNoise(thing Sounder) {
println(thing.Sound())
}

Composition combining data and functions with interfaces and structs

I'm wondering if this is something that's done in Go or if I'm thinking about it all wrong: composing type x interface and type x struct so my interface methods have access to specific data too:
The C programmer in my wants to do this:
type PluginHandler interface {
onLoad()
pm *PluginManager
}
func (ph PluginHandler) onLoad() {
pm.DoSomething()
}
There I have an interface defined with a function, but also some data I want to pass to those functions but this is a syntax error.
So is this something that's doable in Go through some other method or am I just thinking about the problem wrong?
You have defined onLoad incorrectly. You cannot define a function directly on interface type.
Once you have an interface, you need another type to implement methods specified in the interface. For example, if another type implements onLoad method, they automatically (implicitly) implement the interface PluginHandler.
The other thing you need to do is change the interface function type to accept the required data:
type PluginHandler interface {
onLoad(*PluginManager)
}
struct SomeType {
// ...
}
func (s SomeType) onLoad(pm *PluginManager) { // SomeType now implements
pm.DoSomething() // PluginHandler interface.
}
This way, you get to inject whichever PluginManager required by PluginHandler.
Also, you can use SomeType as a PluginHandler type whereever required.
func someFuntion(ph PluginHandler) {
// ...
ph.onLoad(pm)
// ...
}
Can be called with an input argument of type SomeType:
s := SomeType{}
someFunction(s)
TL;DR; There is no direct translation to Go.
Long answer:
Go interfaces are only methods.
Go structs are only data (with the possibility of receiver methods).
You can reference, and even embed interfaces within structs:
type Frobnicator interface {
Frobnicate() error
}
type Widget struct {
Frobnicator
WidgetName string
}
But that's not really what you're talking about.
The best answer to your dilema is, I believe: Take a step back. You're focusing on the trees, and you need to look at the forest. Go takes a different approach than C, or classical OO languages like C++ and Java.
Look at the general problem to be solved, and find solutions to that in Go. This can be a painful process (I can say from experience), but it's really the only way to learn the new way of thinking.
Just for the record, you can add extra methods to an existing type, by introducing another (indirection) type as:
type HandlerManager PluginManager
func (x *HandlerManager) onLoad() {
((*PluginManager)(x)).DoSomething()
}
And if you need to go with a more generic solution, a combination of Adapter & Strategy patterns could do:
type PluginHandlerAdapter struct{ _onLoad func() }
func (x *PluginHandlerAdapter) onLoad() {
x._onLoad()
}
Used like (public/private access ignored):
type PluginManager struct {
PluginHandlerAdapter
}
func NewPluginManager() *PluginManager {
res := new(PluginManager)
res._onLoad = res.DoSomething
return res
}

What situation uses this syntax: thing.Foo().Bar(this)

Can someone show me an example of where this syntax would show up in code?
thing.Foo().Bar(this)
From the looks of it, I see an object that calls a function that calls another function?
I obviously don't know how it works. If you have the slightest idea, I would appreciate a suggestion. Thanks!
This is one of many possible scenarios:
struct somethingelse
{
void SomeOtherMethod()
{
thing.Foo().Bar(this);
}
};
struct foo
{
void Bar(somethingelse *pSomethingElse);
};
struct thing
{
foo &Foo() {return m_foo;}
foo m_foo;
};
What makes this a bit unusual is that the naming convention for the class and method naming is the opposite of the de-facto one in which classes are capitalised and methods camel-cased.
This code could be found in any non-static member function of a class. The Foo() function of thing returns an object of a class with a member function Bar that takes a pointer to the current object (this) as argument.

Resources