diff --git a/pkg/extension/action_handler_test.go b/pkg/extension/action_handler_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f707c399c86509c8fd391286c424ac850096f57
--- /dev/null
+++ b/pkg/extension/action_handler_test.go
@@ -0,0 +1,99 @@
+package extension
+
+import (
+	"context"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestChain(t *testing.T) {
+	tests := []struct {
+		name    string
+		request *ActionRequest
+		router  ActionRouter
+		want    string
+		wantErr bool
+	}{
+		{
+			name:    "No named action call",
+			request: &ActionRequest{Action: "grpc:///ext/action/"},
+			router: func(ctx context.Context, url *ActionURL, req *ActionRequest) (ActionHandler, error) {
+				return func(ctx context.Context, url *ActionURL, req *ActionRequest) (*ActionResponse, error) {
+					return &ActionResponse{State: 0, Msg: "Called - action"}, nil
+				}, nil
+			},
+			want:    "Called - action",
+			wantErr: false,
+		},
+		{
+			name:    "Named action call",
+			request: &ActionRequest{Action: "grpc:///ext/action/"},
+			router: Named("action", func(ctx context.Context, url *ActionURL, req *ActionRequest) (*ActionResponse, error) {
+				return &ActionResponse{State: 0, Msg: "Called named action"}, nil
+			}),
+			want:    "Called named action",
+			wantErr: false,
+		},
+		{
+			name:    "Named action chain call",
+			request: &ActionRequest{Action: "grpc:///ext/action1/"},
+			router: Chain(
+				Named("action1", func(ctx context.Context, url *ActionURL, req *ActionRequest) (*ActionResponse, error) {
+					return &ActionResponse{State: 0, Msg: "Called named action1"}, nil
+				}),
+				Named("action2", func(ctx context.Context, url *ActionURL, req *ActionRequest) (*ActionResponse, error) {
+					return &ActionResponse{State: 0, Msg: "Called named action2"}, nil
+				}),
+			),
+			want:    "Called named action1",
+			wantErr: false,
+		},
+		{
+			name:    "Error (no action in router)",
+			request: &ActionRequest{Action: "grpc:///ext/action3/"},
+			router: Chain(
+				Named("action1", func(ctx context.Context, url *ActionURL, req *ActionRequest) (*ActionResponse, error) {
+					return &ActionResponse{State: 0, Msg: "Called named action1"}, nil
+				}),
+				Named("action2", func(ctx context.Context, url *ActionURL, req *ActionRequest) (*ActionResponse, error) {
+					return &ActionResponse{State: 0, Msg: "Called named action2"}, nil
+				}),
+			),
+			wantErr: true,
+		},
+		{
+			name:    "Named action call with deprecated request",
+			request: &ActionRequest{Action: "action"},
+			router: Named("action", func(ctx context.Context, url *ActionURL, req *ActionRequest) (*ActionResponse, error) {
+				return &ActionResponse{State: 0, Msg: "Called named deprecated action"}, nil
+			}),
+			want:    "Called named deprecated action",
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			url, err := NewActionURL(tt.request.Action)
+			require.NoError(t, err)
+
+			handler, err := tt.router(context.Background(), url, tt.request)
+			if tt.wantErr {
+				require.Error(t, err)
+				return
+			} else {
+				require.NoError(t, err)
+			}
+
+			resp, err := handler(context.Background(), url, tt.request)
+			if tt.wantErr {
+				require.Error(t, err)
+			} else {
+				require.NoError(t, err)
+			}
+
+			assert.Equal(t, tt.want, resp.Msg)
+		})
+	}
+}
diff --git a/pkg/extension/service/extension_test.go b/pkg/extension/service/extension_test.go
index 929f85f3cfa457928ffbcbf368efe1702593f00b..e0582966ae25186f6ddef5014fdd972544521f8a 100644
--- a/pkg/extension/service/extension_test.go
+++ b/pkg/extension/service/extension_test.go
@@ -2,10 +2,10 @@ package service
 
 import (
 	"context"
-	"reflect"
 	"testing"
 
 	"git.perx.ru/perxis/perxis-go/pkg/extension"
+	"github.com/stretchr/testify/require"
 )
 
 func TestExtension_Action(t *testing.T) {
@@ -14,28 +14,28 @@ func TestExtension_Action(t *testing.T) {
 		desc    *extension.ExtensionDescriptor
 		in      *extension.ActionRequest
 		router  extension.ActionRouter
-		want    *extension.ActionResponse
+		want    string
 		wantErr bool
 	}{
 		{
-			name: "OK",
+			name: "Router with 1 named action",
 			desc: &extension.ExtensionDescriptor{Extension: "test", Title: "Test Extension", Description: "desc", Version: "v.0.0.1"},
 			in:   &extension.ActionRequest{Action: "grpc:///test/action", SpaceId: "sp", EnvId: "env", CollectionId: "coll"},
-			want: &extension.ActionResponse{State: extension.ResponseDone},
+			want: "Called action",
 			router: extension.Named("action", func(ctx context.Context, url *extension.ActionURL, req *extension.ActionRequest) (*extension.ActionResponse, error) {
-				return &extension.ActionResponse{State: extension.ResponseDone}, nil
+				return &extension.ActionResponse{State: extension.ResponseDone, Msg: "Called action"}, nil
 			}),
 			wantErr: false,
 		},
 		{
-			name: "OK (chain)",
+			name: "Router with 2 named actions",
 			desc: &extension.ExtensionDescriptor{Extension: "test", Title: "Test Extension", Description: "desc", Version: "v.0.0.1"},
 			in:   &extension.ActionRequest{Action: "grpc:///test/action2", SpaceId: "sp", EnvId: "env", CollectionId: "coll"},
-			want: &extension.ActionResponse{State: extension.ResponseParametersRequired},
+			want: "Called action2",
 			router: extension.Chain(extension.Named("action", func(ctx context.Context, url *extension.ActionURL, req *extension.ActionRequest) (*extension.ActionResponse, error) {
 				return &extension.ActionResponse{State: extension.ResponseDone}, nil
 			}), extension.Named("action2", func(ctx context.Context, url *extension.ActionURL, req *extension.ActionRequest) (*extension.ActionResponse, error) {
-				return &extension.ActionResponse{State: extension.ResponseParametersRequired}, nil
+				return &extension.ActionResponse{State: extension.ResponseDone, Msg: "Called action2"}, nil
 			})),
 			wantErr: false,
 		},
@@ -43,7 +43,6 @@ func TestExtension_Action(t *testing.T) {
 			name: "Error (no extension)",
 			desc: &extension.ExtensionDescriptor{Extension: "test", Title: "Test Extension", Description: "desc", Version: "v.0.0.1"},
 			in:   &extension.ActionRequest{Action: "grpc:///test2/action2", SpaceId: "sp", EnvId: "env", CollectionId: "coll"},
-			want: nil,
 			router: extension.Chain(extension.Named("action", func(ctx context.Context, url *extension.ActionURL, req *extension.ActionRequest) (*extension.ActionResponse, error) {
 				return &extension.ActionResponse{State: extension.ResponseDone}, nil
 			}), extension.Named("action2", func(ctx context.Context, url *extension.ActionURL, req *extension.ActionRequest) (*extension.ActionResponse, error) {
@@ -59,13 +58,11 @@ func TestExtension_Action(t *testing.T) {
 				router: tt.router,
 			}
 			got, err := s.Action(context.Background(), tt.in)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("Action() error = %v, wantErr %v", err, tt.wantErr)
+			if tt.wantErr {
+				require.Error(t, err)
 				return
 			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("Action() got = %v, want %v", got, tt.want)
-			}
+			require.Equal(t, tt.want, got.Msg)
 		})
 	}
 }