Skip to content

Commit

Permalink
Merge pull request #258 from yaziedda/test/lib-store-redis
Browse files Browse the repository at this point in the history
add unit test for lib/store/redis
  • Loading branch information
eko authored Oct 9, 2024
2 parents 4e8b44d + ec7ab9c commit 621044b
Showing 1 changed file with 192 additions and 17 deletions.
209 changes: 192 additions & 17 deletions store/redis/redis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package redis

import (
"context"
"fmt"
"testing"
"time"

Expand Down Expand Up @@ -30,20 +31,65 @@ func TestNewRedis(t *testing.T) {
func TestRedisGet(t *testing.T) {
// Given
ctrl := gomock.NewController(t)
defer ctrl.Finish()

ctx := context.Background()

client := NewMockRedisClientInterface(ctrl)
client.EXPECT().Get(ctx, "my-key").Return(&redis.StringCmd{})

store := NewRedis(client)

// When
value, err := store.Get(ctx, "my-key")

// Then
assert.Nil(t, err)
assert.NotNil(t, value)
tests := []struct {
name string
key string
returnVal string
returnErr error
expectErr bool
expectVal interface{}
}{
{
name: "Returns Value",
key: "my-key",
returnVal: "value",
returnErr: nil,
expectErr: false,
expectVal: "value",
},
{
name: "Key Not Found",
key: "non-existent-key",
returnVal: "",
returnErr: redis.Nil,
expectErr: true,
expectVal: nil,
},
{
name: "Return Error",
key: "my-key",
returnVal: "",
returnErr: fmt.Errorf("some error"),
expectErr: true,
expectVal: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Given: mock the Redis client's Get method
client.EXPECT().Get(ctx, tt.key).Return(redis.NewStringResult(tt.returnVal, tt.returnErr))

// When
value, err := store.Get(ctx, tt.key)

// Then
if tt.expectErr {
assert.Error(t, err)
assert.Equal(t, tt.expectVal, value)
} else {
assert.Nil(t, err)
assert.Equal(t, tt.expectVal, value)
}
})
}
}

func TestRedisSet(t *testing.T) {
Expand Down Expand Up @@ -153,21 +199,53 @@ func TestRedisInvalidate(t *testing.T) {
}

func TestRedisClear(t *testing.T) {
// Given
ctrl := gomock.NewController(t)
defer ctrl.Finish()

ctx := context.Background()

client := NewMockRedisClientInterface(ctrl)
client.EXPECT().FlushAll(ctx).Return(&redis.StatusCmd{})

store := NewRedis(client)

// When
err := store.Clear(ctx)

// Then
assert.Nil(t, err)
tests := []struct {
name string
returnValue *redis.StatusCmd
returnError error
expectError bool
expectedError string
}{
{
name: "Successfully clears data",
returnValue: &redis.StatusCmd{},
returnError: nil,
expectError: false,
},
{
name: "Returns error on failure",
returnValue: redis.NewStatusResult("", fmt.Errorf("flush error")),
returnError: nil,
expectError: true,
expectedError: "flush error",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.expectError {
client.EXPECT().FlushAll(ctx).Return(tt.returnValue).Times(1)
} else {
client.EXPECT().FlushAll(ctx).Return(tt.returnValue).Times(1)
}

err := store.Clear(ctx)

if tt.expectError {
assert.Error(t, err)
assert.Equal(t, tt.expectedError, err.Error())
} else {
assert.NoError(t, err)
}
})
}
}

func TestRedisGetType(t *testing.T) {
Expand All @@ -181,3 +259,100 @@ func TestRedisGetType(t *testing.T) {
// When - Then
assert.Equal(t, RedisType, store.GetType())
}

func TestRedisGetWithTTL(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

ctx := context.Background()
client := NewMockRedisClientInterface(ctrl)
store := NewRedis(client)

t.Run("Returns Value and TTL", func(t *testing.T) {
testReturnsValueAndTTL(t, ctx, client, store)
})

t.Run("Key Not Found", func(t *testing.T) {
testKeyNotFound(t, ctx, client, store)
})

t.Run("Get Error", func(t *testing.T) {
testGetError(t, ctx, client, store)
})

t.Run("TTL Fetch Error", func(t *testing.T) {
testTTLFetchError(t, ctx, client, store)
})
}

func testReturnsValueAndTTL(t *testing.T, ctx context.Context, client *MockRedisClientInterface, store *RedisStore) {
// Given
key := "my-key"
returnValue := "value"
returnTTL := 10 * time.Second
client.EXPECT().
Get(ctx, key).
Return(redis.NewStringResult(returnValue, nil))
client.EXPECT().
TTL(ctx, key).
Return(redis.NewDurationResult(returnTTL, nil))

// When
value, ttl, err := store.GetWithTTL(ctx, key)

// Then
assert.NoError(t, err)
assert.Equal(t, returnValue, value)
assert.Equal(t, returnTTL, ttl)
}

func testKeyNotFound(t *testing.T, ctx context.Context, client *MockRedisClientInterface, store *RedisStore) {
// Given
key := "non-existent-key"
client.EXPECT().
Get(ctx, key).
Return(redis.NewStringResult("", redis.Nil))

// When
value, ttl, err := store.GetWithTTL(ctx, key)

// Then
assert.Error(t, err)
assert.Nil(t, value)
assert.Equal(t, 0*time.Second, ttl)
}

func testGetError(t *testing.T, ctx context.Context, client *MockRedisClientInterface, store *RedisStore) {
// Given
key := "my-key"
client.EXPECT().
Get(ctx, key).
Return(redis.NewStringResult("", fmt.Errorf("some error")))

// When
value, ttl, err := store.GetWithTTL(ctx, key)

// Then
assert.Error(t, err)
assert.Equal(t, nil, value)
assert.Equal(t, 0*time.Second, ttl)
}

func testTTLFetchError(t *testing.T, ctx context.Context, client *MockRedisClientInterface, store *RedisStore) {
// Given
key := "my-key"
client.EXPECT().
Get(ctx, key).
Return(redis.NewStringResult("", nil))
client.EXPECT().
TTL(ctx, key).
Return(redis.NewDurationResult(0, fmt.Errorf("ttl error")))

// When
value, ttl, err := store.GetWithTTL(ctx, key)

// Then
assert.Error(t, err)
assert.Equal(t, nil, value)
assert.Equal(t, 0*time.Second, ttl)
}

0 comments on commit 621044b

Please sign in to comment.