diff --git a/controller/api/apiUtil_test.go b/controller/api/apiUtil_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..bea1ab20500ea125eaf1cea3e557bf615b67f0a9
--- /dev/null
+++ b/controller/api/apiUtil_test.go
@@ -0,0 +1,114 @@
+package api
+
+import (
+	rbacImpl "code.fbi.h-da.de/danet/gosdn/controller/rbac"
+	"github.com/google/uuid"
+)
+
+// Name of this file requires _test at the end, because of how the availability of varibales is handled in test files of go packages.
+// Does not include actual file tests!
+
+const adminID = "5c248a22-8eb7-48cf-b392-45680a1863a5"
+const userID = "57005d13-7a4d-493d-a02b-50ca51c40197"
+const adminRoleID = "126683ae-5ff2-43ee-92f7-0e2b936f8c77"
+const randomRoleName = "bertram"
+
+var adminRoleMap = map[string]string{pndID: "admin"}
+var userRoleMap = map[string]string{pndID: "user"}
+
+func clearAndCreateAuthTestSetup() error {
+	//clear setup if changed
+	storedUsers, err := userService.GetAll()
+	if err != nil {
+		return err
+	}
+	for _, u := range storedUsers {
+		err = userService.Delete(u)
+		if err != nil {
+			return err
+		}
+	}
+
+	storedRoles, err := roleService.GetAll()
+	if err != nil {
+		return err
+	}
+	for _, r := range storedRoles {
+		err = roleService.Delete(r)
+		if err != nil {
+			return err
+		}
+	}
+
+	// create dataset
+	err = createTestUsers()
+	if err != nil {
+		return err
+	}
+
+	err = createTestRoles()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+//TODO(faseid): change password to hashed/encrypted one
+func createTestUsers() error {
+	randomRoleMap := map[string]string{pndID: randomRoleName}
+
+	users := []rbacImpl.User{
+		{UserID: uuid.MustParse(adminID), UserName: "testAdmin", Roles: adminRoleMap, Password: "admin"},
+		{UserID: uuid.MustParse(userID), UserName: "testUser", Roles: userRoleMap, Password: "user"},
+		{UserID: uuid.New(), UserName: "testRandom", Roles: randomRoleMap, Password: "aurelius", Token: "wrong token"},
+	}
+
+	for _, u := range users {
+		err := userService.Add(rbacImpl.NewUser(u.ID(), u.Name(), u.Roles, u.Password, ""))
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func createTestRoles() error {
+	roles := []rbacImpl.Role{
+		{
+			RoleID:      uuid.MustParse(adminRoleID),
+			RoleName:    "adminTestRole",
+			Description: "Admin",
+			Permissions: []string{
+				"/gosdn.core.CoreService/GetPnd",
+				"/gosdn.core.CoreService/GetPndList",
+			},
+		},
+		{
+			RoleID:      uuid.New(),
+			RoleName:    "userTestRole",
+			Description: "User",
+			Permissions: []string{
+				"/gosdn.pnd.PndService/GetChangeList",
+			},
+		},
+		{
+			RoleID:      uuid.New(),
+			RoleName:    randomRoleName,
+			Description: "Not a role",
+			Permissions: []string{
+				"nope",
+			},
+		},
+	}
+
+	for _, r := range roles {
+		err := roleService.Add(rbacImpl.NewRole(r.ID(), r.Name(), r.Description, r.Permissions))
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
diff --git a/controller/api/auth_test.go b/controller/api/auth_test.go
index 9984a36f7b9982d8f4c9cecfa989519d6257b83d..c1e7a24a032919bd6d839922c647dc5e436cfb70 100644
--- a/controller/api/auth_test.go
+++ b/controller/api/auth_test.go
@@ -6,8 +6,6 @@ import (
 	"testing"
 
 	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
-	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
-	"github.com/google/uuid"
 )
 
 func TestLogin(t *testing.T) {
@@ -38,12 +36,6 @@ func TestLogin(t *testing.T) {
 		},
 	}
 
-	err := userService.Add(&rbac.User{UserID: uuid.New(), UserName: "testAdmin", Roles: map[string]string{pndID: "admin"}, Password: "admin"})
-	if err != nil {
-		t.Errorf("Login() error = %v", err)
-		return
-	}
-
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			got, err := Login(tt.args.ctx, tt.args.addr, tt.args.username, tt.args.pwd)
diff --git a/controller/api/initialise_test.go b/controller/api/initialise_test.go
index a0b66962c91b6f03123bebb414da318a543c1101..96fe52536eee5b2b184545d48bcd95aa10ef8459 100644
--- a/controller/api/initialise_test.go
+++ b/controller/api/initialise_test.go
@@ -85,6 +85,7 @@ func bootstrapUnitTest() {
 	sbiStore = nucleus.NewSbiStore(pndUUID)
 	userService = rbacImpl.NewUserService(rbacImpl.NewMemoryUserStore())
 	roleService = rbacImpl.NewRoleService(rbacImpl.NewMemoryRoleStore())
+	clearAndCreateAuthTestSetup()
 
 	previousHostname := "previousHostname"
 	intendedHostname := "intendedHostname"
@@ -142,6 +143,8 @@ func bootstrapUnitTest() {
 	cpb.RegisterCoreServiceServer(s, northbound.Core)
 	ppb.RegisterPndServiceServer(s, northbound.Pnd)
 	apb.RegisterAuthServiceServer(s, northbound.Auth)
+	apb.RegisterUserServiceServer(s, northbound.User)
+	apb.RegisterRoleServiceServer(s, northbound.Role)
 
 	go func() {
 		if err := s.Serve(lis); err != nil {
diff --git a/controller/api/roles.go b/controller/api/role.go
similarity index 100%
rename from controller/api/roles.go
rename to controller/api/role.go
diff --git a/controller/api/users.go b/controller/api/user.go
similarity index 100%
rename from controller/api/users.go
rename to controller/api/user.go
diff --git a/controller/api/user_test.go b/controller/api/user_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..93e37da6c5d8ec84204c1ecf49f49e002c182c20
--- /dev/null
+++ b/controller/api/user_test.go
@@ -0,0 +1,197 @@
+package api
+
+import (
+	"context"
+	"reflect"
+	"testing"
+
+	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
+)
+
+func TestCreateUsers(t *testing.T) {
+	type args struct {
+		ctx   context.Context
+		addr  string
+		users []*apb.User
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    apb.Status
+		wantErr bool
+	}{
+		{
+			name: "default create users",
+			args: args{
+				ctx:  context.TODO(),
+				addr: testAPIEndpoint,
+				users: []*apb.User{
+					{
+						Name:     "foo",
+						Roles:    map[string]string{pndID: "s"},
+						Password: "roh",
+						Token:    "da",
+					},
+				},
+			},
+			want:    apb.Status_STATUS_OK,
+			wantErr: false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := CreateUsers(tt.args.ctx, tt.args.addr, tt.args.users)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("CreateUsers() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got.Status, tt.want) {
+				t.Errorf("CreateUsers() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGetUser(t *testing.T) {
+	type args struct {
+		ctx  context.Context
+		addr string
+		name string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    *apb.GetUserResponse
+		wantErr bool
+	}{
+		{
+			name: "default get user",
+			args: args{
+				ctx:  context.TODO(),
+				addr: testAPIEndpoint,
+				name: "testAdmin",
+			},
+			want: &apb.GetUserResponse{
+				Status: apb.Status_STATUS_OK,
+				User: &apb.User{
+					Id:   adminID,
+					Name: "testAdmin",
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "fail get user",
+			args: args{
+				ctx:  context.TODO(),
+				addr: testAPIEndpoint,
+				name: "foo",
+			},
+			want:    nil,
+			wantErr: true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := GetUser(tt.args.ctx, tt.args.addr, tt.args.name)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GetUser() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != nil && got.Status == tt.want.Status {
+				if got.User.Name != tt.want.User.Name || got.User.Id != tt.want.User.Id {
+					t.Errorf("GetUser() = %v, want %v", got, tt.want)
+				}
+			} else {
+				if got != nil {
+					t.Errorf("GetUser() = %v, want %v", got, tt.want)
+				}
+			}
+		})
+	}
+}
+
+func TestGetAllUsers(t *testing.T) {
+	type args struct {
+		ctx  context.Context
+		addr string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    *apb.GetUsersResponse
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := GetAllUsers(tt.args.ctx, tt.args.addr)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GetAllUsers() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetAllUsers() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestUpdateUsers(t *testing.T) {
+	type args struct {
+		ctx   context.Context
+		addr  string
+		users []*apb.User
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    *apb.UpdateUsersResponse
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := UpdateUsers(tt.args.ctx, tt.args.addr, tt.args.users)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("UpdateUsers() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("UpdateUsers() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestDeleteUsers(t *testing.T) {
+	type args struct {
+		ctx       context.Context
+		addr      string
+		userNames []string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    *apb.DeleteUsersResponse
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := DeleteUsers(tt.args.ctx, tt.args.addr, tt.args.userNames)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("DeleteUsers() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("DeleteUsers() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}