2

I have a package exporting a function that returns a struct pointer that I can't control. I'd like to wrap that function to provide a dependency seam so that I can do some unit testing. The idea is that I want a fake rather than what the external package is giving me.

An example looks like:

/////////////////////////////////////
// External Package I can't control.
/////////////////////////////////////
package ex
type Foo struct {
    v int
}

func (f *Foo) GetV() int {
    return f.v
}

func CreateFoo(v int) *Foo {
    return &Foo{v: v}
}

////////////////////////////////////
// Local Package I'm testing.
////////////////////////////////////
type IFoo interface {
    GetV() int
}

type factory = func(v int) IFoo
var factoryFn factory = ex.CreateFoo

This results in the error: cannot use CreateFoo (type func(int) *Foo) as type func(int) IFoo in assignment

Since I think that *Foo is an IFoo, why not? What am I missing? Is there a way to achieve what I'm trying to do, giving myself a hook like that?

Playground link to example: https://play.golang.org/p/FDckAQGNRgA

3
  • 2
    One option might be var factoryFn factory = func(v int) IFoo { return CreateFoo(v) }. Then you could remove the explicit type and go with var factoryFn = func(v int) IFoo { return CreateFoo(v) } Commented Mar 27, 2019 at 0:00
  • Boy I feel silly. That's a great/easy way to get around the restriction. Thanks! I am a little afraid that I'm misunderstanding something important about the relation between "Struct Pointers" and "Interfaces" though, so I'd still like to know why I can't do that assignment. Commented Mar 27, 2019 at 0:05
  • 1
    I was busy typing a more detailed explanation as an answer when your comment came in. You might want to read up on covariance and contravariance, which would help you understand why the function types are not interchangeable. Commented Mar 27, 2019 at 0:12

1 Answer 1

3

The function type returning IFoo is a different type to the function returning *Foo even though Foo meets the requirements for IFoo, Go does not support covariance on the return type.

You would need to wrap the function

var factoryFn = func(v int) IFoo { return CreateFoo(v) }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.