This repository has been archived by the owner on Oct 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(mock-tests): Mock Arc Client for testing purposes (#26)
* feat(mock-tests): Mock Arc Client for testing purposes * feat(BUX-222): timeout mock arc client added and godocs for creating a mock arc * refactor: timeout mock client added, documentation and better packaging * fix: readme link fix * fix: linter error fix * fix: unused client field
- Loading branch information
1 parent
0976520
commit ad2f0fc
Showing
10 changed files
with
611 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package broadcast_client_mock | ||
|
||
import ( | ||
broadcast_api "github.com/bitcoin-sv/go-broadcast-client/broadcast" | ||
"github.com/bitcoin-sv/go-broadcast-client/broadcast/internal/arc/mocks" | ||
"github.com/bitcoin-sv/go-broadcast-client/broadcast/internal/composite" | ||
) | ||
|
||
// MockType is an enum that is used as parameter to WithMockArc | ||
// client builder in order to create different types of mock. | ||
type MockType int | ||
|
||
const ( | ||
MockSuccess MockType = iota | ||
MockFailure | ||
MockTimeout | ||
) | ||
|
||
type builder struct { | ||
factories []composite.BroadcastFactory | ||
} | ||
|
||
// Builder is used to prepare the mock broadcast client. It is recommended | ||
// to use that builder for creating the mock broadcast client. | ||
func Builder() *builder { | ||
return &builder{} | ||
} | ||
|
||
// WithMockArc creates a mock client for testing purposes. It takes mock type as argument | ||
// and creates a mock client that satisfies the client interface with methods that return | ||
// success or specific error based on this mock type argument. It allows for creating | ||
// multiple mock clients. | ||
func (cb *builder) WithMockArc(mockType MockType) *builder { | ||
var clientToReturn broadcast_api.Client | ||
|
||
switch mockType { | ||
case MockSuccess: | ||
clientToReturn = mocks.NewArcClientMock() | ||
case MockFailure: | ||
clientToReturn = mocks.NewArcClientMockFailure() | ||
case MockTimeout: | ||
clientToReturn = mocks.NewArcClientMockTimeout() | ||
default: | ||
clientToReturn = mocks.NewArcClientMock() | ||
} | ||
|
||
cb.factories = append(cb.factories, func() broadcast_api.Client { | ||
return clientToReturn | ||
}) | ||
return cb | ||
} | ||
|
||
// Build builds the broadcast client based on the provided configuration. | ||
func (cb *builder) Build() broadcast_api.Client { | ||
if len(cb.factories) == 1 { | ||
return cb.factories[0]() | ||
} | ||
return composite.NewBroadcasterWithDefaultStrategy(cb.factories...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
package broadcast_client_mock | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/bitcoin-sv/go-broadcast-client/broadcast" | ||
) | ||
|
||
func TestMockClientSuccess(t *testing.T) { | ||
t.Run("Should successfully query for Policy Quote from mock Arc Client with Success Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockSuccess). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.GetPolicyQuote(context.Background()) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
}) | ||
|
||
t.Run("Should successfully query for Fee Quote from mock Arc Client with Success Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockSuccess). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.GetFeeQuote(context.Background()) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
}) | ||
|
||
t.Run("Should successfully query for transaction from mock Arc Client with Success Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockSuccess). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.QueryTransaction(context.Background(), "test-txid") | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
}) | ||
|
||
t.Run("Should return successful submit transaction response from mock Arc Client with Success Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockSuccess). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.SubmitTransaction(context.Background(), &broadcast.Transaction{RawTx: "test-rawtx"}) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
}) | ||
|
||
t.Run("Should return successful submit batch transactions response from mock Arc Client with Success Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockSuccess). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.SubmitBatchTransactions(context.Background(), []*broadcast.Transaction{{RawTx: "test-rawtx"}, {RawTx: "test2-rawtx"}}) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
}) | ||
} | ||
|
||
func TestMockClientFailure(t *testing.T) { | ||
t.Run("Should return error from GetPolicyQuote method of mock Arc Client with Failure Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockFailure). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.GetPolicyQuote(context.Background()) | ||
|
||
// then | ||
assert.Error(t, err) | ||
assert.Nil(t, result) | ||
assert.EqualError(t, err, broadcast.ErrNoMinerResponse.Error()) | ||
}) | ||
|
||
t.Run("Should return error from GetFeeQuote method of mock Arc Client with Failure Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockFailure). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.GetFeeQuote(context.Background()) | ||
|
||
// then | ||
assert.Error(t, err) | ||
assert.Nil(t, result) | ||
assert.EqualError(t, err, broadcast.ErrNoMinerResponse.Error()) | ||
}) | ||
|
||
t.Run("Should return error from QueryTransaction method of mock Arc Client with Failure Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockFailure). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.QueryTransaction(context.Background(), "test-txid") | ||
|
||
// then | ||
assert.Error(t, err) | ||
assert.Nil(t, result) | ||
assert.EqualError(t, err, broadcast.ErrAllBroadcastersFailed.Error()) | ||
}) | ||
|
||
t.Run("Should return error from SubmitTransaction method of mock Arc Client with Failure Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockFailure). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.SubmitTransaction(context.Background(), &broadcast.Transaction{RawTx: "test-rawtx"}) | ||
|
||
// then | ||
assert.Error(t, err) | ||
assert.Nil(t, result) | ||
assert.EqualError(t, err, broadcast.ErrAllBroadcastersFailed.Error()) | ||
}) | ||
|
||
t.Run("Should return error from SubmitBatchTransaction method of mock Arc Client with Failure Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockFailure). | ||
Build() | ||
|
||
// when | ||
result, err := broadcaster.SubmitBatchTransactions(context.Background(), []*broadcast.Transaction{{RawTx: "test-rawtx"}, {RawTx: "test2-rawtx"}}) | ||
|
||
// then | ||
assert.Error(t, err) | ||
assert.Nil(t, result) | ||
assert.EqualError(t, err, broadcast.ErrAllBroadcastersFailed.Error()) | ||
}) | ||
} | ||
|
||
func TestMockClientTimeout(t *testing.T) { | ||
const defaultTestTime = 200*time.Millisecond | ||
|
||
t.Run("Should successfully query for Policy Quote after a timeout period from mock Arc Client with Timeout Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockTimeout). | ||
Build() | ||
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTime) | ||
defer cancel() | ||
startTime := time.Now() | ||
|
||
// when | ||
result, err := broadcaster.GetPolicyQuote(ctx) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
assert.Greater(t, time.Since(startTime), defaultTestTime) | ||
}) | ||
|
||
t.Run("Should successfully query for Fee Quote after a timeout period from mock Arc Client with Timeout Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockTimeout). | ||
Build() | ||
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTime) | ||
defer cancel() | ||
startTime := time.Now() | ||
|
||
// when | ||
result, err := broadcaster.GetFeeQuote(ctx) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
assert.Greater(t, time.Since(startTime), defaultTestTime) | ||
}) | ||
|
||
t.Run("Should successfully query for transaction after a timeout period from mock Arc Client with Timeout Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockTimeout). | ||
Build() | ||
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTime) | ||
defer cancel() | ||
startTime := time.Now() | ||
|
||
// when | ||
result, err := broadcaster.QueryTransaction(ctx, "test-txid") | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
assert.Greater(t, time.Since(startTime), defaultTestTime) | ||
}) | ||
|
||
t.Run("Should return successful submit transaction response after a timeout period from mock Arc Client with Timeout Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockTimeout). | ||
Build() | ||
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTime) | ||
defer cancel() | ||
startTime := time.Now() | ||
|
||
// when | ||
result, err := broadcaster.SubmitTransaction(ctx, &broadcast.Transaction{RawTx: "test-rawtx"}) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
assert.Greater(t, time.Since(startTime), defaultTestTime) | ||
}) | ||
|
||
t.Run("Should return successful submit batch transactions response after a timeout period from mock Arc Client with Timeout Mock Type", func(t *testing.T) { | ||
// given | ||
broadcaster := Builder(). | ||
WithMockArc(MockTimeout). | ||
Build() | ||
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTime) | ||
defer cancel() | ||
startTime := time.Now() | ||
|
||
// when | ||
result, err := broadcaster.SubmitBatchTransactions(ctx, []*broadcast.Transaction{{RawTx: "test-rawtx"}, {RawTx: "test2-rawtx"}}) | ||
|
||
// then | ||
assert.NoError(t, err) | ||
assert.NotNil(t, result) | ||
assert.Greater(t, time.Since(startTime), defaultTestTime) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.