<https://pkg.go.dev/github.com/pascaldekloe/mqtt@v1.0.0-rc/mqtttest>

The structure encourages people to use function variables instead of method 
invocation (on an object or interface). Do the initialisation from main and 
the unit tests simply mock or stub the relevant calls per method.

func TestFoo(*testing.T) {
        bu := PublishFunc
        defer func() {
                PublishFunc = bu
        }()
        PublishFunc = mqtttest.New...


Op maandag 22 juli 2019 om 07:10:59 UTC+2 schreef wylde...@gmail.com:

> Hello,
>
> I'm new to go (and new to unit testing) and have a question about how to 
> test my code. I have a package that uses a library, with a kinda big 
> interface <https://godoc.org/github.com/eclipse/paho.mqtt.golang>, let's 
> call it A. I don't use all the functions in A, but I want to mock the 
> functionality that I do use from this interface for my unit tests. So I 
> made my own interface that is a subset of the big interface, let's call it 
> B.
>
> The problem is that I would also like to test the construction of the 
> interface. So I made a constructor type that returns B. But I cannot pass 
> the real A constructor function into my package in place of the mock B 
> constructor!
>
> Here's an example
>
> package main
>
>
> // A is an interface that does X, Y and Z
> type A interface {
>   X()
>   Y()
>   Z()
> }
>
> // B is a strict subset of A.
> type B interface {
>   X()
>   Y()
> }
>
> // AConstructor claims to build an interface that does A
> func AConstructor() A {
>   return nil
> }
>
> // BConstructorType is a type of function that returns a B interface
> type BConstructorType func() B
>
>
> // Initialize creates a B and calls the methods in the interface. (I want 
> to be able to mock A and test this function)
> func Initialize(constructor BConstructorType) {
>   b := constructor()
>   b.X()
>   b.Y()
> }
>
>
> func main() {
>   // cannot use AConstructor (type func() A) as type BConstructorType in 
> argument to Initialize Initialize(AConstructor)
>   Initialize(AConstructor)
> }
>
> Why is AConstructor not of type BConstructorType? It seems like the type 
> system is interpreting it's definition quite literally. Would this change 
> the current compiler implementation a lot to support this kind of smart 
> type checking?
>
> I know I can use a closure to curry the constructor arguments and have an 
> explicit return type as a workaround
> func main() {
>   Initialize(func() B { return AConstructor() })
> }
> but it feels clunky and unnecessary, and seems to be a bad way to have to 
> call my Initialize method outside of the package
>
> Furthermore, if I define the curried constructor as a function in my 
> package to ease the pain, then it will give me a warning if B is not 
> exported.
> // exported func ConstructRealA returns unexported type B, which can be 
> annoying to use
> func ConstructRealA() B {
>  return AConstructor()
> }
>
>
> Do y'all have any thoughts on this? Am I going about this wrong? Should I 
> change the way I'm testing to avoid the whole constructor problem? I know 
> generics have been considered as an addition to the language, but would 
> generics solve this problem? 
>
> Thanks,
> Kevin
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/8fed92e1-9000-40ff-948f-5538702ecf23n%40googlegroups.com.

Reply via email to