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.