Skip to content

Commit c7bd96a

Browse files
tests: add tests for redis kv (#72)
* tests: add tests for redis kv * chore: Updated coverage badge. --------- Co-authored-by: GitHub Action <[email protected]>
1 parent a773908 commit c7bd96a

File tree

4 files changed

+188
-5
lines changed

4 files changed

+188
-5
lines changed

Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Propeller 𖣘
2-
![Coverage](https://img.shields.io/badge/Coverage-12.0%25-red)
2+
![Coverage](https://img.shields.io/badge/Coverage-12.3%25-red)
33
[![Go Report Card](https://goreportcard.com/badge/github.com/CRED-CLUB/propeller)](https://goreportcard.com/report/github.com/CRED-CLUB/propeller)
44
[![CHECKS](https://github.com/CRED-CLUB/propeller/actions/workflows/checks.yaml/badge.svg)](https://github.com/CRED-CLUB/propeller/actions/workflows/checks.yaml/badge.svg)
55
[![GoDoc](https://godoc.org/github.com/CRED-CLUB/propeller?status.svg)](https://godoc.org/github.com/CRED-CLUB/propeller) <a href="https://starcharts.herokuapp.com/CRED-CLUB/propeller"><img alt="Stars" src="https://img.shields.io/github/stars/CRED-CLUB/propeller.svg?style=social"></a>

internal/kv/redis.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import (
66
redispkg "github.com/CRED-CLUB/propeller/pkg/broker/redis"
77
)
88

9-
// Redis ...
9+
// Redis implements IKV interface using Redis
1010
type Redis struct {
11-
redisClient *redispkg.Client
11+
redisClient redispkg.IKVClient
1212
}
1313

1414
// NewRedis returns redis kv client
15-
func NewRedis(client *redispkg.Client) IKV {
15+
func NewRedis(client redispkg.IKVClient) IKV {
1616
return &Redis{client}
1717
}
1818

internal/kv/redis_test.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package kv
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
redispkg "github.com/CRED-CLUB/propeller/pkg/broker/redis"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/mock"
11+
)
12+
13+
// Define a common error for testing
14+
var errTestFailed = errors.New("test error")
15+
16+
// MockRedisClient is a mock implementation of the redispkg.IKVClient interface
17+
type MockRedisClient struct {
18+
mock.Mock
19+
}
20+
21+
// Ensure MockRedisClient implements redispkg.IKVClient
22+
var _ redispkg.IKVClient = (*MockRedisClient)(nil)
23+
24+
func (m *MockRedisClient) HSet(ctx context.Context, key string, values ...interface{}) error {
25+
args := m.Called(ctx, key, values)
26+
return args.Error(0)
27+
}
28+
29+
func (m *MockRedisClient) HGetAll(ctx context.Context, key string) (map[string]string, error) {
30+
args := m.Called(ctx, key)
31+
return args.Get(0).(map[string]string), args.Error(1)
32+
}
33+
34+
func (m *MockRedisClient) Delete(ctx context.Context, key string, fields ...string) error {
35+
args := m.Called(ctx, key, fields)
36+
return args.Error(0)
37+
}
38+
39+
func TestNewRedis(t *testing.T) {
40+
mockClient := new(MockRedisClient)
41+
redis := NewRedis(mockClient)
42+
43+
assert.NotNil(t, redis)
44+
assert.Implements(t, (*IKV)(nil), redis)
45+
46+
// Type assertion to verify the internal client is set correctly
47+
redisImpl, ok := redis.(*Redis)
48+
assert.True(t, ok)
49+
assert.Equal(t, mockClient, redisImpl.redisClient)
50+
}
51+
52+
func TestRedis_Store(t *testing.T) {
53+
ctx := context.Background()
54+
55+
t.Run("successful store", func(t *testing.T) {
56+
mockClient := new(MockRedisClient)
57+
redis := NewRedis(mockClient)
58+
59+
// The Redis implementation will call HSet with field and value as separate arguments
60+
mockClient.On("HSet", ctx, "test-key", []interface{}{"field1", "value1"}).Return(nil).Once()
61+
62+
err := redis.Store(ctx, "test-key", "field1", "value1")
63+
64+
assert.NoError(t, err)
65+
mockClient.AssertExpectations(t)
66+
})
67+
68+
t.Run("error on store", func(t *testing.T) {
69+
mockClient := new(MockRedisClient)
70+
redis := NewRedis(mockClient)
71+
72+
mockClient.On("HSet", ctx, "test-key", []interface{}{"field1", "value1"}).Return(errTestFailed).Once()
73+
74+
err := redis.Store(ctx, "test-key", "field1", "value1")
75+
76+
assert.Error(t, err)
77+
assert.Equal(t, errTestFailed, err)
78+
mockClient.AssertExpectations(t)
79+
})
80+
}
81+
82+
func TestRedis_Load(t *testing.T) {
83+
ctx := context.Background()
84+
85+
t.Run("successful load with data", func(t *testing.T) {
86+
mockClient := new(MockRedisClient)
87+
redis := NewRedis(mockClient)
88+
89+
expectedData := map[string]string{
90+
"field1": "value1",
91+
"field2": "value2",
92+
}
93+
94+
mockClient.On("HGetAll", ctx, "test-key").Return(expectedData, nil).Once()
95+
96+
result, err := redis.Load(ctx, "test-key")
97+
98+
assert.NoError(t, err)
99+
assert.Equal(t, expectedData, result)
100+
mockClient.AssertExpectations(t)
101+
})
102+
103+
t.Run("successful load with empty data", func(t *testing.T) {
104+
mockClient := new(MockRedisClient)
105+
redis := NewRedis(mockClient)
106+
107+
expectedData := map[string]string{}
108+
109+
mockClient.On("HGetAll", ctx, "test-key").Return(expectedData, nil).Once()
110+
111+
result, err := redis.Load(ctx, "test-key")
112+
113+
assert.NoError(t, err)
114+
assert.Empty(t, result)
115+
mockClient.AssertExpectations(t)
116+
})
117+
118+
t.Run("error on load", func(t *testing.T) {
119+
mockClient := new(MockRedisClient)
120+
redis := NewRedis(mockClient)
121+
122+
mockClient.On("HGetAll", ctx, "test-key").Return(map[string]string(nil), errTestFailed).Once()
123+
124+
result, err := redis.Load(ctx, "test-key")
125+
126+
assert.Error(t, err)
127+
assert.Equal(t, errTestFailed, err)
128+
assert.Nil(t, result)
129+
mockClient.AssertExpectations(t)
130+
})
131+
}
132+
133+
func TestRedis_Delete(t *testing.T) {
134+
ctx := context.Background()
135+
136+
t.Run("successful delete single field", func(t *testing.T) {
137+
mockClient := new(MockRedisClient)
138+
redis := NewRedis(mockClient)
139+
140+
mockClient.On("Delete", ctx, "test-key", []string{"field1"}).Return(nil).Once()
141+
142+
err := redis.Delete(ctx, "test-key", "field1")
143+
144+
assert.NoError(t, err)
145+
mockClient.AssertExpectations(t)
146+
})
147+
148+
t.Run("successful delete multiple fields", func(t *testing.T) {
149+
mockClient := new(MockRedisClient)
150+
redis := NewRedis(mockClient)
151+
152+
fields := []string{"field1", "field2"}
153+
mockClient.On("Delete", ctx, "test-key", fields).Return(nil).Once()
154+
155+
err := redis.Delete(ctx, "test-key", fields...)
156+
157+
assert.NoError(t, err)
158+
mockClient.AssertExpectations(t)
159+
})
160+
161+
t.Run("error on delete", func(t *testing.T) {
162+
mockClient := new(MockRedisClient)
163+
redis := NewRedis(mockClient)
164+
165+
mockClient.On("Delete", ctx, "test-key", []string{"field1"}).Return(errTestFailed).Once()
166+
167+
err := redis.Delete(ctx, "test-key", "field1")
168+
169+
assert.Error(t, err)
170+
assert.Equal(t, errTestFailed, err)
171+
mockClient.AssertExpectations(t)
172+
})
173+
}

pkg/broker/redis/redis.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,21 @@ type IRedis interface {
2121
RemoveSubscription(ctx context.Context, channel string, s broker.ISubscription) error
2222
}
2323

24-
// Client holds redis client
24+
// IKVClient defines the interface for Redis key-value operations
25+
type IKVClient interface {
26+
HSet(ctx context.Context, key string, values ...interface{}) error
27+
HGetAll(ctx context.Context, key string) (map[string]string, error)
28+
Delete(ctx context.Context, key string, fields ...string) error
29+
}
30+
31+
// Client holds redis client and implements IKVClient
2532
type Client struct {
2633
client redis.UniversalClient
2734
}
2835

36+
// Ensure Client implements IKVClient
37+
var _ IKVClient = (*Client)(nil)
38+
2939
// NewClient returns a new redis client
3040
func NewClient(config Config) *Client {
3141
var tlsConfig *tls.Config = nil

0 commit comments

Comments
 (0)