go-redis / redismock

Redis client Mock
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
280 stars 60 forks source link

Empty result in HGET operation in TxPipelined #28

Closed bereal closed 2 years ago

bereal commented 2 years ago

Hello, I have already asked the question about it on StackOverflow, but I have a strong suspicion that it may be a bug. I'm mocking an HGET operation, but when I call this operation inside a TxPipelined, the result is empty. It doesn't return an error either, like it would do if this was a mock expectation setup error. Here is the code that reproduces my problem:

package test

import (
    "context"
    "testing"
    "github.com/go-redis/redis/v8"
    "github.com/go-redis/redismock/v8"
)

func TestMock(t *testing.T) {
    ctx := context.TODO()

    db, mock := redismock.NewClientMock()
    mock.ExpectWatch("key")
    mock.ExpectTxPipeline()
    mock.ExpectHGet("key", "field").SetVal("VALUE")

    var result string
    db.Watch(ctx, func(tx *redis.Tx) error {
        _, err := tx.TxPipelined(ctx, func(p redis.Pipeliner) error {
            // Here I'd expect r to be "VALUE"
            r, err := p.HGet(ctx, "key", "field").Result()
            t.Logf("Result: '%s', error: %+v", r, err)
            result = r
            return err
        })

        return err
    }, "key")

    if result != "VALUE" {
        t.Errorf("Expected result to be VALUE, got %s", result)
    }
}

The test fails with the error:

--- FAIL: TestMock (0.00s)
    redis_test.go:26: Result: '', error: <nil>
    redis_test.go:36: Expected result to be VALUE, got ''

Without a pipeline, the code works like expected.

bereal commented 2 years ago

I realized that I was calling HGet on p instead of tx.