Giter VIP home page Giter VIP logo

redigomock's Introduction

redigomock

Build Status GoDoc

Easy way to unit test projects using redigo library (Redis client in go). You can find the latest release here.

install

go get -u github.com/rafaeljusto/redigomock/v3

usage

Here is an example of using redigomock, for more information please check the API documentation.

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
	"github.com/rafaeljusto/redigomock/v3"
)

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
}

func main() {
	// Simulate command result

	conn := redigomock.NewConn()
	cmd := conn.Command("HGETALL", "person:1").ExpectMap(map[string]string{
		"name": "Mr. Johson",
		"age":  "42",
	})

	person, err := RetrievePerson(conn, "1")
	if err != nil {
		fmt.Println(err)
		return
	}

	if conn.Stats(cmd) != 1 {
		fmt.Println("Command was not used")
		return
	}

	if person.Name != "Mr. Johson" {
		fmt.Printf("Invalid name. Expected 'Mr. Johson' and got '%s'\n", person.Name)
		return
	}

	if person.Age != 42 {
		fmt.Printf("Invalid age. Expected '42' and got '%d'\n", person.Age)
		return
	}

	// Simulate command error

	conn.Clear()
	cmd = conn.Command("HGETALL", "person:1").ExpectError(fmt.Errorf("Simulate error!"))

	person, err = RetrievePerson(conn, "1")
	if err == nil {
		fmt.Println("Should return an error!")
		return
	}

	if conn.Stats(cmd) != 1 {
		fmt.Println("Command was not used")
		return
	}

	fmt.Println("Success!")
}

mocking a subscription

package main

import "github.com/rafaeljusto/redigomock/v3"

func CreateSubscriptionMessage(data []byte) []interface{} {
	values := []interface{}{}
	values = append(values, interface{}([]byte("message")))
	values = append(values, interface{}([]byte("chanName")))
	values = append(values, interface{}(data))
	return values
}

func main() {
	conn := redigomock.NewConn()

	// Setup the initial subscription message
	values := []interface{}{}
	values = append(values, interface{}([]byte("subscribe")))
	values = append(values, interface{}([]byte("chanName")))
	values = append(values, interface{}([]byte("1")))

	conn.Command("SUBSCRIBE", subKey).Expect(values)
	conn.ReceiveWait = true

	// Add a response that will come back as a subscription message
	conn.AddSubscriptionMessage(CreateSubscriptionMessage([]byte("hello")))

	// You need to send messages to conn.ReceiveNow in order to get a response.
	// Sending to this channel will block until receive, so do it in a goroutine
	go func() {
		conn.ReceiveNow <- true // This unlocks the subscribe message
		conn.ReceiveNow <- true // This sends the "hello" message
	}()
}

connections pool

// Note you cannot get access to the connection via the pool,
// the only way is to use this conn variable.
conn := redigomock.NewConn()
pool := &redis.Pool{
	// Return the same connection mock for each Get() call.
	Dial:    func() (redis.Conn, error) { return conn, nil },
	MaxIdle: 10,
}

dynamic handling arguments

Sometimes you need to check the executed arguments in your Redis command. For that you can use the command handler.

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
	"github.com/rafaeljusto/redigomock/v3"
)

func Publish(conn redis.Conn, x, y int) error {
	if x < 0 {
		x = 0
	}
	if y < 0 {
		y = 0
	}
	_, err := conn.Do("PUBLISH", "sumCh", int64(x+y))
	return err
}

func main() {
	conn := redigomock.NewConn()
	conn.GenericCommand("PUBLISH").Handle(redigomock.ResponseHandler(func(args []interface{}) (interface{}, error) {{
		if len(args) != 2 {
			return nil, fmt.Errorf("unexpected number of arguments: %d", len(args))
		}
		v, ok := args[1].(int64)
		if !ok {
			return nil, fmt.Errorf("unexpected type %T", args[1])
		}
		if v < 0 {
			return nil, fmt.Errorf("unexpected value '%d'", v)
		}
		return int64(1), nil
	})

	if err := Publish(conn, -1, 10); err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("Success!")
}

redigomock's People

Contributors

aphistic avatar benjaminjkraft avatar clawconduce avatar dmathieu avatar drewlandis avatar jekiapp avatar lentil1016 avatar merlincox avatar mingan avatar mitchsw avatar rafaeljusto avatar shanehowearth avatar szank avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

redigomock's Issues

Documentation Limitation

func TestCheckPasswordFailures_MoreThan5(t *testing.T) {

conn := redigomock.NewConn()

conn.Command("EXISTS", "[email protected]_pwf").Expect(true)
conn.Command("GET", "[email protected]_pwf").Expect(6)

actual := checkPasswordFailures(conn, mockUser)

assert.False(t, actual)

}

[error] error in checkPasswordFailures: redigo: unexpected type for Bool, got type bool

There is some documentation on mapping to a struct, but nothing at all about basic values such as strings, ints, bools. How do I respond to the command with a Bool or an int?

Here's the function being tested:
var checkPasswordFailures = func(client redis.Conn, u *User) bool {

var userkey = getPasswordFailKey(u)
var existing, err = redis.Bool(client.Do("EXISTS", userkey))

fmt.Printf("%s - existing = %v\n", userkey, existing)

if err != nil {
    Log.Errorf("error in checkPasswordFailures: %s", err.Error())
}
if existing == true {
    fmt.Println("Existing true")
    reply, err := redis.Int(client.Do("GET", userkey))

    Log.Debug("Attempt Count: %d", reply)

    if err != nil {
        Log.Errorf("error in checkPasswordFailures: %s", err.Error())
    }
    return reply < 5
}
fmt.Println("Using default")
return true

}

Behavior of `Send` is awkward.

I've found that when I use Send in my code, I have great difficulty achieving the results I would like in terms of tests. I basically have to make a spurious Do call, since nothing else forces a flush of the command queue and expectations apparently aren't checked against that queue.

Would it make sense to have the Flush method actually flush this queue (then modify Do to call the Flush command)? If so, would that be best handled as a default implementation (I.E. something that would not be done if a FlushMock function is provided), or as something that's always performed, regardless of whether a FlushMock is provided?

Or am I perhaps misunderstanding how I should be testing Send commands?

Support for cluster

Any plans to support github.com/chasex/redis-go-cluster? It can be a killer feature

Mocking an error on a subscription

Hi

As of v3, I am finding trouble mocking an error on a subscription, which in previous versions was accomplished by using the field "Error" in the SubResponses

Best regards

error:command SUBSCRIBE with arguments []interface {}{"example"} not registered in redigomock library

I had some trouble using this to emulate a pubsub connection in a manner similiar to redigo:
I might be doing something wrong here, but this is what I'm trying:

main.go

import "github.com/garyburd/redigo/redis"

func ReadMessages(c redis.Conn, redisChannel string) <-chan string {
    messages := make(chan string)

    go func() {
        psc := redis.PubSubConn{Conn: c}
        psc.Subscribe(redisChannel)
        for {
            switch v := psc.Receive().(type) {
            case redis.Message:
                messages <- string(v.Data)
            case error:
                messages <- "error:" + v.Error()
                close(messages)
                return
            }
        }
    }()

    return messages
}

test.go

import (
    "github.com/rafaeljusto/redigomock"
    "testing"
)
func TestRedisPubSub(t *testing.T) {
    redisChannel := "example"

    c := redigomock.NewConn()
    messages := ReadMessages(c, redisChannel)
    defer c.Close()
    t.Log("Started subscriber connection")

    conn := redigomock.NewConn()
    defer conn.Close()
    t.Log("Started publisher connection")

    SendMessages(conn, "example", "Uno")
    SendMessages(conn, "example", "Deux")
    SendMessages(conn, "example", "Three")
    SendMessages(conn, "example", "Finised")
    t.Log("Sent messages")

    conn.Flush()

    counter := 0
    for msg := range messages {
        t.Logf("Recieved a message: %s ", msg)
        counter++
        if msg == "Finised" {
            break
        }
    }
    if counter != 4 {
        t.Logf("Failed, expected 4 messages, recieved %d", counter)
        t.Fatal("Incorrect message count")
        return
    }
    t.Log("Succesful redis pub sub test")
}

And I get the following output:

=== RUN   TestRedisPubSub
--- FAIL: TestRedisPubSub (0.00s)
    redis_publisher_test.go:80: Started subscriber connection
    redis_publisher_test.go:87: Started publisher connection
    redis_publisher_test.go:93: Sent messages
    redis_publisher_test.go:99: Recieved a message: error:command SUBSCRIBE with arguments []interface {}{"example"} not registered in redigomock library
    redis_publisher_test.go:106: Failed, expected 4 messages, recieved 1
    redis_publisher_test.go:107: Incorrect message count

ZREMRANGEBYSCORE not registered

It seems ZREMRANGEBYSCORE does not work as expected.

I got :
command ZREMRANGEBYSCORE with arguments []interface {}{"key", "0", "1495533556"} not registered in redigomock library

Several methods are not safe for concurrent use

Do is mostly safe (although see #59 and #61), but other commands are not.

In general it's not possible to fully solve this problem -- Do and Errors, for example, cannot be made safe from each other without breaking compatibility, since Errors is a public field. So in #59 I just documented it as a problem. But there may be some cases that are possible to improve. Here's a race detector trace which shows one possible problem:

WARNING: DATA RACE
Write at 0x00c0002ff7d8 by goroutine 91: 
  github.com/rafaeljusto/redigomock.(*Conn).removeRelatedCommands()
      /home/benkraft/.go/pkg/mod/github.com/rafaeljusto/[email protected]+incompatible/redigomock.go:136 +0x224
  github.com/rafaeljusto/redigomock.(*Conn).Command()
      /home/benkraft/.go/pkg/mod/github.com/rafaeljusto/[email protected]+incompatible/redigomock.go:78 +0x13d
[continues into our code calling Command()]

Previous read at 0x00c0002ff7d8 by goroutine 95:
  github.com/rafaeljusto/redigomock.(*Conn).find()
      /home/benkraft/.go/pkg/mod/github.com/rafaeljusto/[email protected]+incompatible/redigomock.go:115 +0x42
  github.com/rafaeljusto/redigomock.(*Conn).do()
      /home/benkraft/.go/pkg/mod/github.com/rafaeljusto/[email protected]+incompatible/redigomock.go:192 +0x94
  github.com/rafaeljusto/redigomock.(*Conn).Do()
      /home/benkraft/.go/pkg/mod/github.com/rafaeljusto/[email protected]+incompatible/redigomock.go:188 +0x4a3
  github.com/gomodule/redigo/redis.(*activeConn).Do()
      /home/benkraft/.go/pkg/mod/github.com/gomodule/[email protected]+incompatible/redis/pool.go:447 +0x1d6
[continues into our code calling Do()]

You can see the two are racing on c.commands, which makes sense.

Unfortunately I can't share the test at issue, but basically what it does is

// prod code
func DeleteInBackground() {
  go conn.Do("DELETE", ...)
}

// test
conn := ...
conn.Command(...).Expect(...)

DeleteInBackground()

conn.Command(...).Expect(...)

It's not clear what this test was doing was really right, but ideally it would at least be race-detector-clean.

Using gocheck testing framework

Hi,
I was wondering if it would be ok to introduce dependency on gocheck testing framework http://labix.org/gocheck.

It is really nice improvement compared to go builtin test framework. And both of them can be used simultaneously in the same package.

Suggested change for new release

Hi Rafael,
You have created 1.0 tag, so I can suggest slight modification to redigomock behaviour.
We have discussed it before. If you force redigomock Do() command arguments to be matched only in the order they have been called ( overriding this issue #1 ) you could simplify fuzzy/non fuzzy command matching, treating every command as it was a fuzzy one.

What do you think about this idea? I think that the current situation is a bit confusing: if there is no fuzzy mach, then arguments can be given in any order, but if there is at least one fuzzy matcher, then the argument order have to mach the one given in the mock command definition.

I am OK with leaving it as it is if you don't want to change it, and I will clarify documentation either way.

Best regards,
Maciej

unexpected type for Strings, got type []string

Hello.

I am trying to add:
conn.Command("ZRANGEBYSCORE", "last_message_at", "-inf", timestamp).Expect([]string{"123"})

Then in my app code:
ids, err := redis.Strings(conn.Do("ZRANGEBYSCORE", "last_message_at", "-inf", timestamp))

And when I try to access in my test it I get
redigo: unexpected type for Strings, got type []string

Application code works ok backed by real redis.

As far as I can tell Strings does return a []string in redigo. Am I misunderstanding something?

Thank you very much in advance.
T

More helpful message when failing to match

I added something like this to help me debug a problem I was having:

diff --git a/github.com/rafaeljusto/redigomock/redigomock.go b/github.com/rafaeljusto/redigomo
index 112fc33..aadd5ab 100644
--- a/github.com/rafaeljusto/redigomock/redigomock.go
+++ b/github.com/rafaeljusto/redigomock/redigomock.go
@@ -152,6 +152,11 @@ func (c *Conn) Do(commandName string, args ...interface{}) (reply interface{}, e
        if cmd == nil {
                // Didn't find a specific command, try to get a generic one
                if cmd = c.find(commandName, nil); cmd == nil {
+                       for _, regCmd := range c.commands {
+                               if commandName == regCmd.Name {
+                                       fmt.Printf("%s possible match for\n%#v:\n%#v", commandName, args, regCmd.Args)
+                               }
+                       }
                        return nil, fmt.Errorf("command %s with arguments %#v not registered in redigomock library",
                                commandName, args)
                }

It is pretty hacky, but I think something like this would be useful either in the error msg or printed out to screen.

Feature: fail when command stub isn't called

It would be great if, in addition to setting command stubs, there was an option to fail if said stub was not called during the test (Similar to RSpec's allow vs expect syntax).

Apologies if this is already part of the library, I was unable to find it if so.

Gopkg is out of date

The gopkg v1 points to a version that (afaik) doesnt work. Possible to add a tag and update gopkg.in ?

Mocking a call to `Do` that involves a `nil` parameter blows up.

I have a call to Do, of the form Do("some_command", ..., nil, ...) and I would like to mock it. Unfortunately, when I do so, I get a panic, because implementsFuzzy blows up when given nil, due to the assumption that reflect.TypeOf(nil) will return a non-nil value.

A more durable construction might be:

func implementsFuzzy(input interface{}) bool {
	inputType := reflect.TypeOf(input)
	if inputType == nil {
		return false
	}
	return inputType.Implements(reflect.TypeOf((*FuzzyMatcher)(nil)).Elem())
}

Command arguments order

The redigomock library cannot find the registered command when the executed command have the same arguments but in a different order.

GPL license - dual licensing possible?

In order to use the library in commercial projects a non-viral license would be needed (MIT, Apache-2.0, BSD). Would it be possible to change the license from GPL to non-limiting or provide dual licensing?

I really appreciate any help you can provide.

Feature: support for redis.Pool

My solution is to create a real redis.Pool that returns a redigomock.Conn:

    mockRedisConn         = redigomock.NewConn()
    mockRedisPool         = &redis.Pool{Dial: func () (redis.Conn, error) { return mockRedisConn, nil }}

conn.Close generates a call to Do()

Hello here,

while testing redigomock with this simple function:

func (r *RedisCaching) Version() (string, error) {
	conn := r.Pool.Get()
	defer conn.Close()

	version, err := redis.String(conn.Do("GET", "version"))
	return version, err
}
	Context("given a list of nodes and a redis reader", func() {

		var (
			mockRedisConn *redigomock.Conn
			mockRedisPool *redis.Pool
		)

		JustBeforeEach(func() {
			mockRedisConn = redigomock.NewConn()

			mockRedisPool = redis.NewPool(func() (redis.Conn, error) {
				return mockRedisConn, nil
			}, 10)

			updater = &RedisCaching{
				Pool:      mockRedisPool,
				BulkScans: 10,
			}
		})

		It("should update the nodes to the caching datastore", func() {
			_ = mockRedisConn.Command("GET", "version").Expect("1")
			_, err := updater.Version()
			fmt.Printf("%v\n", mockRedisConn)
		})
	})

I get the following unwanted call to Do()

DO  0 []

&{[] false 0xc420021740 <nil> <nil> <nil> [0xc4200115e0] [] map[GETversion:1] {{0 0} 0 0 0 0} [command  with arguments []interface {}(nil) not registered in redigomock library]}

printed from the redigomock library itself adding the line:

func (c *Conn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
	fmt.Printf("DO %s %d %v\n", commandName, len(c.queue), c.queue)

the call is generated by defer Close() and disappears when I remove that line.

Thanks!

Feature: support for Redis streams

I've recently found the need to mock stream responses (which are in a pretty grim format) and it would be great to be able to have a helper function that generated a stream response based on a stream name, messageID, and a map. I've implemented a rudimentary version for my own testing purposes, but it would be nice to have this as part of this mocking lib. Is this in the pipeline? I would be happy to contribute if this is something you think would be useful to people. Otherwise if there is already a nice way of doing this that I've missed could you add it to the documentation?

Thanks in advance!

How to simulate slow redis calls?

Hi. Firstly, thanks for this great package. It's really useful.

However, I'm having an issue with trying to create a test case for a long blocking function. In this case I'm doing a BRPOP with a 10 second timeout, then retrying if nothing received (this is to avoid TCP read timeouts). I'm unsure how to mock this though. It seems the conn.Command only allows registering determined responses. Ideally I'd need to test one nil response then a second successful response. I realise I could do Clear() then re-register the command, but this causes a race condition. It would be great would be if we could register a function to a command. That gives the flexibility to do all sorts of fun things like responding differently each time, or adding a large delay to the response.

LLEN and LINDEX not being recognized

It seems like RPUSH, GET commands work as intended.

conn.Do("RPUSH", "key", object) // Works fine
conn.Do("LLEN, "key", object) // Not working

LLEN and LINDEX throws an error, "registered in redigomock library"

Adding fuzzy argument matching ( like regexes or values in range [-1, 5] for example )

Hi, I am am passing a time.Now().Unix() as a argument to redis. This means that in the mock I can't provide just a "concrete" value.

I am planning to add fuzzy matching for example :
intForType := 1

Command( "some string", 1 , Any { intForType }, Range{ -10.0, 10,0 }, RegexMatch{"[Rr]edigo"}, true)

To make it work the arguments passed to Command and the ones passed to mock connection have to be in the same order. Otherwise everything will just explode when more than one provided regex could match string passed to mock connection for example.

I am planning to add a new method : FuzzyCommand which will return a FuzzyCommand struct stored in separate list ( not in the "concrete" command list ).

It is a big change, so I want to check what do you think about it before i submit a pull request :)

Best regards

Publish new release

The latest release (v2.0.0) doesn't contain the new ExpectSlice method. Would it be possible to publish a new version which contains this method?

The change set is: ca49a8a...master

If there are no breaking changes in here, then we can publish v2.1.0, otherwise, v3.0.0.

Thanks.

Problem testing simple non-transactional pipelining

I may be misunderstanding how this package is supposed to work, but I think there might be an issue with how this mock handles simple non-transactional pipelining. I was trying to test some code that uses redigo/redis to pipeline two commands: GET key followed by EXPIRE key ttl. There's no need to do this as a transaction, so the code follows the simple pipelining example in the redigo documentation:

	conn.Send("GET", key)
	conn.Send("EXPIRE", key, ttlDuration.Seconds())
	conn.Flush()

	//GET command reply
	getReply, err := redis.Bytes(conn.Receive())
	if err != nil {
		return fmt.Errorf("error executing GET: %v", err)
	}

        //do something with getReply bytes

This seems to work correctly when run against a real redis server. But when I try to test this with the redigomock package, I always get an error when calling conn.Receive(), regardless of whether I use .Expect() or .ExpectError(). The error text is "no more items" and it's returned from here:

return nil, fmt.Errorf("no more items")

For example, my unit test code looks something like this:

conn := redigomock.NewConn()
conn.Command("GET", key).Expect([]bytes("testing"))
conn.Command("EXPIRE", key, ttlDuration.Seconds()).Expect(1)
if err := callMyFunction(conn); err != nil {
        //this error always occurs
}

From what I can see in the code, the mock connection's .Send() method adds the commands to c.queue:

c.queue = append(c.queue, queueElement{

But it appears that the .Flush() method empties that c.queue, calling c.do() for each:

c.queue = []queueElement{}

At the top of the .Receive() method, the code tests whether len(c.queue) == 0, which in this case will always be true, so I always get that "no more items" error.

if len(c.queue) == 0 {

That said, I'm still trying to discern how this package works, so let me know if I've misunderstood something!

Accessing redigomock.Conn

I've been trying for a couple of days to use the connection from redis.Pool in my tests, but am having lots of fail. I've pasted my test code below, with commented out attempts and their error messages. I'd prefer not to have to refactor my code to pass around a connection, as there is a connection attached to the instance of the struct that the method comes with

package rediscache

import (
	"log"
	"os"
	"testing"

	"github.com/gomodule/redigo/redis"
	"github.com/rafaeljusto/redigomock"
	v1 "github.com/shanehowearth/cloudblog/readarticle/integration/grpc/gen/v1"
	"github.com/stretchr/testify/assert"
)

var testR Redis


func TestMain(m *testing.M) {
	log.Print("Test Main")

	conn := redigomock.NewConn()
	mockPool := &redis.Pool{
		// Return the same connection mock for each Get() call.
		Dial:    func() (redis.Conn, error) { return conn, nil },
		MaxIdle: 10,
	}
	log.Printf("TM connection %v", mockPool.Get())
	testR = Redis{pool: mockPool}
	log.Print("Exit test main")
	os.Exit(m.Run())
}

func TestGetByTitle(t *testing.T) {
	log.Print("Enter TestGetByTitle")
	testcases := map[string]struct {
		title string
	}{
		"Happy Path": {title: "Success"},
	}
	for name, tc := range testcases {
		t.Run(name, func(t *testing.T) {
			log.Printf("Calling %s\n", name)
			cmd := testR.pool.Get()
                        // cmd := testR.pool.Get().(redigomock.Conn) // fails with  testR.pool.Get() (value of type github.com/gomodule/redigo/redis.Conn) cannot have dynamic type github.com/rafaeljusto/redigomock.Conn (missing method Close) 
                        // cmd := redigomock.Conn(testR.pool.Get()) // fails with cannot convert testR.pool.Get() (value of type github.com/gomodule/redigo/redis.Conn) to github.com/rafaeljusto/redigomock.Conn 
			// cmd := redigomock.NewConn() // fails with invalid operation: cmd (variable of type *github.com/rafaeljusto/redigomock.Conn) is not an interface 
			log.Printf("Mock cmd: %v", cmd)
			cmd.(redigomock.Conn).Command("HGET", "articles:lookup:title", "Success").Expect(int64(1))
			output := testR.GetByTitle(tc.title)
			assert.Equal(t, &v1.Article{Title: tc.title}, output, "Article returned did not match expected")
		})
	}
}

ConnWithTimeout support

When I use redis.DoWithTimeout on my code, I get redis: connection does not support ConnWithTimeout error on tests with the redigomock.Conn.

I can implement the redis.ConnWithTimeout interface by wrapping the mock like:

type wrapConn struct {
  *redigomock.Conn
}

func (c wrapConn) DoWithTimeout(timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
  return c.Conn.Do(cmd, args...)
}

func (c wrapConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
  return c.Conn.Receive()
}

It works well, but considering all redis.Conn implementations in the redigo package support the redis.ConnWithTimeout interface, it would be nice if redigomock.Conn also support it by itself.

I believe simply ignoring the timeout argument like above is enough, since we can mock a timeout error with ExpectError.

Any thoughts?

Issue on redis.Bool or redis.Int commands

func TestSomeFunc(t *testing.T) {
conn := redigomock.NewConn()
conn.Command("EXISTS","KEY").Expect(true)
conn.Command("GET","KEY2").Expect(1)
some_function(conn)
}

func some_function(conn redis.Conn) {
r, err := redis.Bool(conn.Do("EXISTS", "KEY"))
fmt.Println(r)
r, err = conn.Do("EXISTS", "KEY")
fmt.Println(r)
r, err = redis.Int(conn.Do("GET", "KEY2"))
fmt.Println(r)
r, err = conn.Do("GET", "KEY2")
fmt.Println(r)
}

Output:
false
true
0
1

Why am i getting false and 0 on applying redis.Bool and redis.Int commands & how to solve this ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.