2

I am trying to write some tests for an existing library but cannot get gomock to work

I would like to test behaviour if rand.Read fails. Here is an example of what I would like to test. I would like to see the log.Error line executing in test

import (
     "crypto/rand"
)
    func GetRandomBytes(n int) ([]byte, error) {

        b := make([]byte, n)
        _, err := rand.Read(b)

        if err != nil {
            log.Error("Failed to get entropy from system", err)
            return nil, err
        }

        return b, nil
    }

The gomock system should let me force the "rand.Read" call to do the right thing

However, I cannot get the mockgen tool to work in "reflect" mode

$ $GOPATH/bin/mockgen 'crypto/rand' Read
# command-line-arguments
./prog.go:22:28: invalid indirect of "crypto/rand".Read (type func([]byte) (int, error))
2018/01/21 11:20:30 Loading input failed: exit status 2

I'm using go version go1.9.2 linux/amd64 on Ubuntu 14.04

genmock -prog_only 'crypto/rand' Read works fine, but the code it generates doesn't look useful for what I need to do

Vorsprung
  • 32,923
  • 5
  • 39
  • 63

1 Answers1

2

I’ve had the same task recently. Also tried to mock, but finally make in another way.

You can make a function accepting Read function and returning your target function GetRandomBytes. Like:

func MakeRandomBytesGetter(fn func([]byte) (int,error)) func(int)([]bute,error) {
    return func(n int) ([]byte, error) {

        b := make([]byte, n)
        _, err := fn(b)

        if err != nil {
            log.Error("Failed to get entropy from system", err)
            return nil, err
        }

        return b, nil
    }
}

var (
    GetRamdomBytes = MakeRandomBytesGetter(rand.Read)
)

For tests you can use different functions with the same signature but another behavior. Like:

func FailRead(n int) ([]byte, error) {
    return []byte{}, fmt.Errorf("Read failed")
}

And check you function behavior when it gets such errors.

Eugene Lisitsky
  • 12,113
  • 5
  • 38
  • 59
  • Looks good, I'll have to inform the owners of the function being checked. Once I've implemented the test I'll accept the answer, upvote etc etc – Vorsprung Jan 22 '18 at 11:13