Skip to content

Commit

Permalink
add some tests and some refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
mehdihadeli committed Aug 3, 2022
1 parent 6647056 commit dac2b83
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 11 deletions.
4 changes: 2 additions & 2 deletions examples/cqrs/internal/products/api/products_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (pc *ProductsController) createProduct() echo.HandlerFunc {
}

command := creatingProduct.NewCreateProductCommand(request.Name, request.Description, request.Price)
result, err := mediatr.Send[*creatingProductsDtos.CreateProductCommandResponse](ctx.Request().Context(), command)
result, err := mediatr.Send[*creatingProduct.CreateProductCommand, *creatingProductsDtos.CreateProductCommandResponse](ctx.Request().Context(), command)

if err != nil {
return err
Expand Down Expand Up @@ -76,7 +76,7 @@ func (pc *ProductsController) getProductByID() echo.HandlerFunc {
return err
}

queryResult, err := mediatr.Send[*gettingProductByIdDtos.GetProductByIdQueryResponse](ctx.Request().Context(), query)
queryResult, err := mediatr.Send[*gettingProductById.GetProductByIdQuery, *gettingProductByIdDtos.GetProductByIdQueryResponse](ctx.Request().Context(), query)

if err != nil {
return err
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/spec v0.20.4 // indirect
Expand All @@ -27,6 +28,9 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.11 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.4.0 // indirect
github.com/stretchr/testify v1.8.0 // indirect
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
Expand All @@ -37,4 +41,5 @@ require (
golang.org/x/tools v0.1.10 // indirect
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,15 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/swaggo/echo-swagger v1.3.3 h1:Fx8kQ8IcIIEL3ZE20wzvcT8gFnPo/4U+fsnS3I1wvCw=
github.com/swaggo/echo-swagger v1.3.3/go.mod h1:vbKcEBeJgOexLuPcsdZhrRAV508fsE79xaKIqmvse98=
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe h1:K8pHPVoTgxFJt1lXuIzzOX7zZhZFldJQK/CgKx9BFIc=
Expand Down Expand Up @@ -156,3 +161,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
15 changes: 8 additions & 7 deletions mediatr.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package mediatr

import (
"context"
"fmt"
"github.com/pkg/errors"
"reflect"
)

Expand All @@ -14,14 +14,15 @@ var requestHandlersRegistrations = map[reflect.Type]interface{}{}

type Unit struct{}

// RegisterRequestHandler register the handler to mediatr registry.
// RegisterRequestHandler register the request handler to mediatr registry.
func RegisterRequestHandler[TRequest any, TResponse any](h RequestHandler[TRequest, TResponse]) error {
var request TRequest
requestType := reflect.TypeOf(request)

_, exist := requestHandlersRegistrations[requestType]
if exist {
return fmt.Errorf("registerd handler already registered for message %T", requestType)
// each request in request/response strategy should have just one handler
return errors.Errorf("registered handler already exists in the registry for message %s", requestType.String())
}

requestHandlersRegistrations[requestType] = h
Expand All @@ -35,23 +36,23 @@ func RegisterRequestBehavior(b interface{}) error {
}

// Send the request to its corresponding handler.
func Send[TResponse any, TRequest any](ctx context.Context, request TRequest) (TResponse, error) {
func Send[TRequest any, TResponse any](ctx context.Context, request TRequest) (TResponse, error) {

requestType := reflect.TypeOf(request)

handler, ok := requestHandlersRegistrations[requestType]
if !ok {
return *new(TResponse), fmt.Errorf("no handlers for command %T", request)
return *new(TResponse), errors.Errorf("no handlers for command %T", request)
}

handlerValue, ok := handler.(RequestHandler[TRequest, TResponse])
if !ok {
return *new(TResponse), fmt.Errorf("handler for command %T is not a Handler", request)
return *new(TResponse), errors.Errorf("handler for command %T is not a Handler", request)
}

response, err := handlerValue.Handle(ctx, request)
if err != nil {
return *new(TResponse), err
return *new(TResponse), errors.Wrap(err, "error handling request")
}

return response, nil
Expand Down
93 changes: 93 additions & 0 deletions mediatr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package mediatr

import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"testing"
)

func Test_RegisterRequestHandler_Should_Return_Error_If_Handler_Already_Registered(t *testing.T) {
expectedErr := fmt.Sprintf("registered handler already exists in the registry for message %s", "*mediatr.RequestTest")
handler1 := &RequestTestHandler{}
handler2 := &RequestTestHandler{}
err1 := RegisterRequestHandler[*RequestTest, *ResponseTest](handler1)
err2 := RegisterRequestHandler[*RequestTest, *ResponseTest](handler2)

assert.Nil(t, err1)
assert.Containsf(t, err2.Error(), expectedErr, "expected error containing %q, got %s", expectedErr, err2)
}

func Test_RegisterRequestHandler_Should_Register_All_Handlers(t *testing.T) {
handler1 := &RequestTestHandler{}
handler2 := &RequestTestHandler2{}
err1 := RegisterRequestHandler[*RequestTest, *ResponseTest](handler1)
err2 := RegisterRequestHandler[*RequestTest2, *ResponseTest2](handler2)

assert.Nil(t, err1)
assert.Nil(t, err2)
}

func Test_Send_Should_Throw_Error_If_No_Handler_Registered(t *testing.T) {
expectedErr := fmt.Sprintf("no handlers for command %T", &RequestTest{})
_, err := Send[*RequestTest, *ResponseTest](context.Background(), &RequestTest{Data: "test"})
assert.Containsf(t, err.Error(), expectedErr, "expected error containing %q, got %s", expectedErr, err)
}

func Test_Send_Should_Return_Error_If_Handler_Returns_Error(t *testing.T) {
expectedErr := "error handling request"
handler3 := &RequestTestHandler3{}
_ = RegisterRequestHandler[*RequestTest2, *ResponseTest2](handler3)
_, err := Send[*RequestTest2, *ResponseTest2](context.Background(), &RequestTest2{Data: "test"})
assert.Containsf(t, err.Error(), expectedErr, "expected error containing %q, got %s", expectedErr, err)
}

func Test_Send_Should_Return_Response_If_Handler_Returns_Success(t *testing.T) {
handler := &RequestTestHandler{}
_ = RegisterRequestHandler[*RequestTest, *ResponseTest](handler)
response, err := Send[*RequestTest, *ResponseTest](context.Background(), &RequestTest{Data: "test"})
assert.Nil(t, err)
assert.IsType(t, &ResponseTest{}, response)
assert.Equal(t, "test", response.Data)
}

///////////////////////////////////////////////////////////////////////////////////////////////
type RequestTest struct {
Data string
}

type ResponseTest struct {
Data string
}

type RequestTestHandler struct {
}

func (c *RequestTestHandler) Handle(ctx context.Context, request *RequestTest) (*ResponseTest, error) {
return &ResponseTest{Data: request.Data}, nil
}

///////////////////////////////////////////////////////////////////////////////////////////////
type RequestTest2 struct {
Data string
}

type ResponseTest2 struct {
Data string
}

type RequestTestHandler2 struct {
}

func (c *RequestTestHandler2) Handle(ctx context.Context, request *RequestTest2) (*ResponseTest2, error) {
return &ResponseTest2{Data: request.Data}, nil
}

///////////////////////////////////////////////////////////////////////////////////////////////
type RequestTestHandler3 struct {
}

func (c *RequestTestHandler3) Handle(ctx context.Context, request *RequestTest2) (*ResponseTest2, error) {
return nil, errors.New("some error")
}
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ command := &CreateProductCommand{
CreatedAt: time.Now(),
}

mediatr.Send[*creatingProductsDtos.CreateProductCommandResponse](ctx, command)
mediatr.Send[*CreateProductCommand, *creatingProductsDtos.CreateProductCommandResponse](ctx, command)
```

```go
Expand All @@ -172,7 +172,7 @@ query := &GetProdctByIdQuery{
ProductID: uuid.NewV4()
}

mediatr.Send[*gettingProductsDtos.GetProdctByIdQueryResponse](ctx, query)
mediatr.Send[*GetProdctByIdQuery, *gettingProductsDtos.GetProdctByIdQueryResponse](ctx, query)
```


Expand Down

0 comments on commit dac2b83

Please sign in to comment.