Documentation ¶
Overview ¶
Package redigomock is a mock for redigo library (redis client)
Redigomock basically register the commands with the expected results in a internal global variable. When the command is executed via Conn interface, the mock will look to this global variable to retrieve the corresponding result.
To start a mocked connection just do the following:
c := redigomock.NewConn()
Now you can inject it whenever your system needs a redigo.Conn because it satisfies all interface requirements. Before running your tests you need beyond of mocking the connection, registering the expected results. For that you can generate commands with the expected results.
redigomock.Command("HGETALL", "person:1").Expect("Person!") redigomock.Command( "HMSET", []string{"person:1", "name", "John"}, ).Expect("ok")
As the Expect method from Command receives anything (interface{}), another method was created to easy map the result to your structure. For that use ExpectMap:
redigomock.Command("HGETALL", "person:1").ExpectMap(map[string]string{ "name": "John", "age": 42, })
You should also test the error cases, and you can do it in the same way of a normal result.
redigomock.Command("HGETALL", "person:1").ExpectError(fmt.Errorf("Low level error!"))
Sometimes you will want to register a command regardless the arguments, and you can do it with the method GenericCommand (mainly with the HMSET).
redigomock.GenericCommand("HMSET").Expect("ok")
All commands are registered in a global variable, so they will be there until all your test cases ends. So for good practice in test writing you should in the beginning of each test case clear the mock states.
redigomock.Clear()
Let's see a full test example. Imagine a Person structure and a function that pick up this person in Redis using redigo library (file person.go):
package person import ( "fmt" "github.com/garyburd/redigo/redis" ) type Person struct { Name string `redis:"name"` Age int `redis:"age"` } func RetrievePerson(conn redis.Conn, id string) (Person, error) { var person Person values, err := redis.Values(conn.Do("HGETALL", fmt.Sprintf("person:%s", id))) if err != nil { return person, err } err = redis.ScanStruct(values, &person) return person, err }
Now we need to test it, so let's create the corresponding test with redigomock (fileperson_test.go):
package person import ( "github.com/rafaeljusto/redigomock" "testing" ) func TestRetrievePerson(t *testing.T) { redigomock.Clear() redigomock.Command("HGETALL", "person:1").ExpectMap(map[string]string{ "name": "Mr. Johson", "age": "42", }) person, err := RetrievePerson(redigomock.NewConn(), "1") if err != nil { t.Fatal(err) } if person.Name != "Mr. Johson" { t.Errorf("Invalid name. Expected 'Mr. Johson' and got '%s'", person.Name) } if person.Age != 42 { t.Errorf("Invalid age. Expected '42' and got '%d'", person.Age) } } func TestRetrievePersonError(t *testing.T) { redigomock.Clear() redigomock.Command("HGETALL", "person:1").ExpectError(fmt.Errorf("Simulate error!")) person, err = RetrievePerson(redigomock.NewConn(), "1") if err == nil { t.Error("Should return an error!") } }
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Cmd ¶
type Cmd struct { Name string // Name of the command Args []interface{} // Arguments of the command Responses []Response // Slice of returned responses }
Cmd stores the registered information about a command to return it later when request by a command execution
func Command ¶
Command register a command in the mock system using the same arguments of a Do or Send commands. It will return a registered command object where you can set the response or error
func GenericCommand ¶
GenericCommand register a command without arguments. If a command with arguments doesn't match with any registered command, it will look for generic commands before throwing an error
func Script ¶
Script registers a command in the mock system just like Command method would do The first argument is a byte array with the script text, next ones are the ones you would pass to redis Script.Do() method
func (*Cmd) Expect ¶
Expect sets a response for this command. Everytime a Do or Receive methods are executed for a registered command this response or error will be returned. You cannot set a response and a error for the same command/arguments
func (*Cmd) ExpectError ¶
ExpectError allows you to force an error when executing a command/arguments
type Conn ¶
type Conn struct { ReceiveWait bool // When set to true, Receive method will wait for a value in ReceiveNow channel to proceed, this is useful in a PubSub scenario ReceiveNow chan bool // Used to lock Receive method to simulate a PubSub scenario CloseMock func() error // Mock the redigo Close method ErrMock func() error // Mock the redigo Err method FlushMock func() error // Mock the redigo Flush method }
Conn is the struct that can be used where you inject the redigo.Conn on your project
func (Conn) Do ¶
Do looks in the registered commands (via Command function) if someone matchs with the given command name and arguments, if so the corresponding response or error is returned. If no registered command is found an error is returned