I'm trying to unit test some code (pasted below). I've struggled to find a way to mock the amqp.Connection, so have decided to go the monkey patching route.
My /thought/ was to check os.Getenv("GO_GCFLAGS"), but as I was kindly reminded, executng the tests and compiling the tests are two different things.
My next brilliant idea was to use a build tag to ensure that the test file is only built when the flags are set as I desire. But
https://golang.org/pkg/go/build/ doesn't offer any ideas where gcflags might be checked, or what tag to use.
So, I throw myself at the mercy of golang-nuts to (gently) point me in the right direction (I completely understand that there may be an easier way to do this, but I cannot see that path)
```
### Code to test
// MQ -
type MQ struct {
conn *amqp.Connection
Retry int
URI string
}
// Connect -
func (mq *MQ) Connect() (err error) {
// Retry MUST be > 0
if mq.Retry == 0 {
log.Print("Cannot use a Retry of zero, this process will to default retry to 1")
mq.Retry = 1
}
// Note: Even though amqp.ParseURI(uri) will validate the URI formed, check here that the minimum required exists
if mq.URI == "" {
log.Printf("No Message Queue URI configured")
}
for {
for i := 0; i < mq.Retry; i++ {
mq.conn, err = amqp.Dial(mq.URI)
if err == nil {
// Successful connection
log.Printf("Successfully connected to RabbitMQ")
return nil
}
time.Sleep(1 * time.Second)
}
// Log that there is a problem connecting to the RabbitMQ service that needs urgent attention
backoff := time.Duration(mq.Retry*rand.Intn(10)) * time.Second
log.Printf("ALERT: Trouble connecting to RabbitMQ, error: %v, going to re-enter retry loop in %s seconds", err, backoff.String())
time.Sleep(backoff)
}
}
### Test Code
func TestConnect(t *testing.T) {
testcases := map[string]struct {
retry int
uri string
err error
}{
"Happy Path": {retry: 1, uri: "amqp://localhost:5672/%2f"},
}
for name, tc := range testcases {
t.Run(name, func(t *testing.T) {
// Monkeypatch amqp to return the nil and the error
fakeRabbitConnection := func(msg string) (*amqp.Connection, error) {
return nil, tc.err // I only want the error to have meaning, therefore the connection can be nil (which also saves me having to create a mock)
}
patch := monkey.Patch(amqp.Dial, fakeRabbitConnection)
defer patch.Unpatch()
mq := rabbit.MQ{Retry: tc.retry, URI: tc.uri}
output := mq.Connect()
fmt.Println(output) // TODO
})
}
}
```