Stubbing package methods

I’m co-authoring a package that has a dependency on a package called paho.mqtt.golang. My package speaks MQTT to an IoT cloud using ‘paho’.
I want to test my package without actually sending requests to the cloud by stubbing some of the methods that ‘paho’ provides such as Connect, Publish, etc. Most of these methods are written such that they accept an interface and return either an interface or a basic type.

Token and 'Client` are interfaces in ‘paho’.

type Client interface {
	IsConnected() bool
	Connect() Token
	Disconnect(uint)
	Publish(string, byte, bool, interface{}) Token
	Subscribe(string, byte, MessageHandler) Token
	SubscribeMultiple(map[string]byte, MessageHandler) Token
	Unsubscribe(...string) Token
}
type Token interface {
	Wait() bool
	WaitTimeout(time.Duration) bool
	flowComplete()
	Error() error
}

Maybe my code looks something like this where I’ll set the Token according to the test case.

type MockToken struct {
    ready bool
    err   error
}

func (mt *MockToken) Wait() bool {
    return mt.ready
}

func (mt *MockToken) WaitTimeout(time.Duration) bool {
    return mt.ready
}

func (mt *MockToken) flowComplete() {
    mt.ready = true
    return
}

func (mt *MockToken) Error() error {
    return mt.err
}
import (
     MQTT "github.com/eclipse/paho.mqtt.golang"
)

type MockClient struct {
    isConnected bool
    token       MQTT.Token
}

func (mc *MockClient) IsConnected() bool {
    return mc.isConnected
}

func (mc *MockClient) Connect() MQTT.Token {
    return mc.token
}

func (mc *MockClient) Disconnect(quiesce uint) {
    return
}

func (mc *MockClient) Publish(topic string, qos byte, retained bool, payload interface{}) MQTT.Token {
    return mc.token
}

func (mc *MockClient) Subscribe(topic string, qos byte, callback MQTT.MessageHandler) MQTT.Token {
    return mc.token
}

func (mc *MockClient) SubscribeMultiple(filters map[string]byte, callback MQTT.MessageHandler) MQTT.Token {
    return mc.token
}

func (mc *MockClient) Unsubscribe(topics ...string) MQTT.Token {
    return mc.token
}

The test case looks like this

func TestMQTTGatewayConnectMustReturnError(t *testing.T) {
    var newClient = NewClient
    oldNewClient := newClient
    defer func() { newClient = oldNewClient }()

    newClient = func(config *GatewayConfig) MQTT.Client {
        fmt.Println("mocked newClient")
        return &MockClient{true, &MockToken{}}
    }
    ...
}

Link to Github issue.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.