diff --git a/client/src/app/instance/store/effects/search.effects.spec.ts b/client/src/app/instance/store/effects/search.effects.spec.ts
index a8883613bd739aa34849aaf4b9856da775ebb89c..d7485658f0c4b0120a08b025f1bfe7bfcd40494f 100644
--- a/client/src/app/instance/store/effects/search.effects.spec.ts
+++ b/client/src/app/instance/store/effects/search.effects.spec.ts
@@ -52,7 +52,7 @@ describe('[Instance][Store] SearchEffects', () => {
                     }},
                 { provide: ToastrService, useValue: { error: jest.fn() }},
                 provideMockActions(() => actions),
-                provideMockStore({ initialState }),
+                provideMockStore({ initialState })
             ]
         }).compileComponents();
         effects = TestBed.inject(SearchEffects);
diff --git a/client/src/app/metamodel/effects/output-family.effects.spec.ts b/client/src/app/metamodel/effects/output-family.effects.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5a8ab2bc1fbef58576d4d999c5cf439673277f28
--- /dev/null
+++ b/client/src/app/metamodel/effects/output-family.effects.spec.ts
@@ -0,0 +1,315 @@
+import { TestBed } from '@angular/core/testing';
+import { Router } from '@angular/router';
+
+import { provideMockActions } from '@ngrx/effects/testing';
+import { EffectsMetadata, getEffectsMetadata } from '@ngrx/effects';
+import { Observable } from 'rxjs';
+import { cold, hot } from 'jasmine-marbles';
+import { ToastrService } from 'ngx-toastr';
+
+import { OutputFamilyEffects } from './output-family.effects';
+import { OutputFamilyService } from '../services/output-family.service';
+import * as outputFamilyActions from '../actions/output-family.actions';
+import { OUTPUT_FAMILY, OUTPUT_FAMILY_LIST } from '../../../test-data';
+import { MockStore, provideMockStore } from '@ngrx/store/testing';
+import * as datasetSelector from '../selectors/dataset.selector';
+
+describe('[Metamodel][Effects] OutputFamilyEffects', () => {
+    let actions = new Observable();
+    let effects: OutputFamilyEffects;
+    let metadata: EffectsMetadata<OutputFamilyEffects>;
+    let service: OutputFamilyService;
+    let toastr: ToastrService;
+    let store: MockStore;
+    const initialState = { metamodel: { } };
+    let mockDatasetSelectorSelectDatasetNameByRoute;
+    let router: Router;
+
+    beforeEach(() => {
+        TestBed.configureTestingModule({
+            providers: [
+                OutputFamilyEffects,
+                { provide: OutputFamilyService, useValue: { }},
+                { provide: Router, useValue: { navigate: jest.fn() }},
+                { provide: ToastrService, useValue: {
+                        success: jest.fn(),
+                        error: jest.fn()
+                    }},
+                provideMockActions(() => actions),
+                provideMockStore({ initialState })
+            ]
+        }).compileComponents();
+        effects = TestBed.inject(OutputFamilyEffects);
+        metadata = getEffectsMetadata(effects);
+        service = TestBed.inject(OutputFamilyService);
+        toastr = TestBed.inject(ToastrService);
+        router = TestBed.inject(Router);
+        store = TestBed.inject(MockStore);
+        mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector(
+            datasetSelector.selectDatasetNameByRoute,''
+        );
+    });
+
+    it('should be created', () => {
+        expect(effects).toBeTruthy();
+    });
+
+    describe('loadOutputFamilies$ effect', () => {
+        it('should dispatch the loadOutputFamilyListSuccess action on success', () => {
+            mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector(
+                datasetSelector.selectDatasetNameByRoute, 'myDataset'
+            );
+
+            const action = outputFamilyActions.loadOutputFamilyList();
+            const outcome = outputFamilyActions.loadOutputFamilyListSuccess({ outputFamilies: OUTPUT_FAMILY_LIST });
+
+            actions = hot('-a', { a: action });
+            const response = cold('-a|', { a: OUTPUT_FAMILY_LIST });
+            const expected = cold('--b', { b: outcome });
+            service.retrieveOutputFamilyList = jest.fn(() => response);
+
+            expect(effects.loadOutputFamilies$).toBeObservable(expected);
+            expect(service.retrieveOutputFamilyList).toHaveBeenCalledWith('myDataset');
+        });
+
+        it('should dispatch the loadOutputFamilyListFail action on HTTP failure', () => {
+            const action = outputFamilyActions.loadOutputFamilyList();
+            const error = new Error();
+            const outcome = outputFamilyActions.loadOutputFamilyListFail();
+
+            actions = hot('-a', { a: action });
+            const response = cold('-#|', { }, error);
+            const expected = cold('--b', { b: outcome });
+            service.retrieveOutputFamilyList = jest.fn(() => response);
+
+            expect(effects.loadOutputFamilies$).toBeObservable(expected);
+        });
+    });
+
+    describe('addOutputFamilies$ effect', () => {
+        it('should dispatch the addSurveySuccess action on success', () => {
+            mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector(
+                datasetSelector.selectDatasetNameByRoute, 'myDataset'
+            );
+
+            const action = outputFamilyActions.addOutputFamily({ outputFamily: OUTPUT_FAMILY });
+            const outcome = outputFamilyActions.addOutputFamilySuccess({ outputFamily: OUTPUT_FAMILY });
+
+            actions = hot('-a', { a: action });
+            const response = cold('-a|', { a: OUTPUT_FAMILY });
+            const expected = cold('--b', { b: outcome });
+            service.addOutputFamily = jest.fn(() => response);
+
+            expect(effects.addOutputFamilies$).toBeObservable(expected);
+            expect(service.addOutputFamily).toHaveBeenCalledWith('myDataset', OUTPUT_FAMILY);
+        });
+
+        it('should dispatch the addOutputFamilyFail action on HTTP failure', () => {
+            const action = outputFamilyActions.addOutputFamily({ outputFamily: OUTPUT_FAMILY });
+            const error = new Error();
+            const outcome = outputFamilyActions.addOutputFamilyFail();
+
+            actions = hot('-a', { a: action });
+            const response = cold('-#|', { }, error);
+            const expected = cold('--b', { b: outcome });
+            service.addOutputFamily = jest.fn(() => response);
+
+            expect(effects.addOutputFamilies$).toBeObservable(expected);
+        });
+    });
+
+    describe('addOutputFamilySuccess$ effect', () => {
+        it('should not dispatch', () => {
+            expect(metadata.addOutputFamilySuccess$).toEqual(
+                expect.objectContaining({ dispatch: false })
+            );
+        });
+
+        it('should display a success notification', () => {
+            const spy = jest.spyOn(toastr, 'success');
+            const action = outputFamilyActions.addOutputFamilySuccess({ outputFamily: OUTPUT_FAMILY });
+
+            actions = hot('a', { a: action });
+            const expected = cold('a', { a: action });
+
+            expect(effects.addOutputFamilySuccess$).toBeObservable(expected);
+            expect(spy).toHaveBeenCalledTimes(1);
+            expect(spy).toHaveBeenCalledWith(
+                'Output family successfully added',
+                'The new output family was added into the database'
+            );
+        });
+    });
+
+    describe('addOutputFamilyFail$ effect', () => {
+        it('should not dispatch', () => {
+            expect(metadata.addOutputFamilyFail$).toEqual(
+                expect.objectContaining({ dispatch: false })
+            );
+        });
+
+        it('should display an error notification', () => {
+            const spy = jest.spyOn(toastr, 'error');
+            const action = outputFamilyActions.addOutputFamilyFail();
+
+            actions = hot('a', { a: action });
+            const expected = cold('a', { a: action });
+
+            expect(effects.addOutputFamilyFail$).toBeObservable(expected);
+            expect(spy).toHaveBeenCalledTimes(1);
+            expect(spy).toHaveBeenCalledWith(
+                'Failure to add output family',
+                'The new output family could not be added into the database'
+            );
+        });
+    });
+
+    describe('editOutputFamily$ effect', () => {
+        it('should dispatch the editSurveySuccess action on success', () => {
+            const action = outputFamilyActions.editOutputFamily({ outputFamily: OUTPUT_FAMILY });
+            const outcome = outputFamilyActions.editOutputFamilySuccess({ outputFamily: OUTPUT_FAMILY });
+
+            actions = hot('-a', { a: action });
+            const response = cold('-a|', { a: OUTPUT_FAMILY });
+            const expected = cold('--b', { b: outcome });
+            service.editOutputFamily = jest.fn(() => response);
+
+            expect(effects.editOutputFamily$).toBeObservable(expected);
+        });
+
+        it('should dispatch the editSurveyFail action on HTTP failure', () => {
+            const action = outputFamilyActions.editOutputFamily({ outputFamily: OUTPUT_FAMILY });
+            const error = new Error();
+            const outcome = outputFamilyActions.editOutputFamilyFail();
+
+            actions = hot('-a', { a: action });
+            const response = cold('-#|', { }, error);
+            const expected = cold('--b', { b: outcome });
+            service.editOutputFamily = jest.fn(() => response);
+
+            expect(effects.editOutputFamily$).toBeObservable(expected);
+        });
+    });
+
+    // describe('editSurveySuccess$ effect', () => {
+    //     it('should not dispatch', () => {
+    //         expect(metadata.editSurveySuccess$).toEqual(
+    //             expect.objectContaining({ dispatch: false })
+    //         );
+    //     });
+    //
+    //     it('should display a success notification', () => {
+    //         const toastrSpy = jest.spyOn(toastr, 'success');
+    //         const routerSpy = jest.spyOn(router, 'navigate');
+    //         const action = outputFamilyActions.editSurveySuccess({ survey: SURVEY });
+    //
+    //         actions = hot('a', { a: action });
+    //         const expected = cold('a', { a: action });
+    //
+    //         expect(effects.editSurveySuccess$).toBeObservable(expected);
+    //         expect(toastrSpy).toHaveBeenCalledTimes(1);
+    //         expect(toastrSpy).toHaveBeenCalledWith(
+    //             'Survey successfully edited',
+    //             'The existing survey has been edited into the database'
+    //         );
+    //         expect(routerSpy).toHaveBeenCalledTimes(1);
+    //         expect(routerSpy).toHaveBeenCalledWith(['/admin/survey/survey-list']);
+    //     });
+    // });
+    //
+    // describe('editSurveyFail$ effect', () => {
+    //     it('should not dispatch', () => {
+    //         expect(metadata.editSurveyFail$).toEqual(
+    //             expect.objectContaining({ dispatch: false })
+    //         );
+    //     });
+    //
+    //     it('should display an error notification', () => {
+    //         const spy = jest.spyOn(toastr, 'error');
+    //         const action = outputFamilyActions.editSurveyFail();
+    //
+    //         actions = hot('a', { a: action });
+    //         const expected = cold('a', { a: action });
+    //
+    //         expect(effects.editSurveyFail$).toBeObservable(expected);
+    //         expect(spy).toHaveBeenCalledTimes(1);
+    //         expect(spy).toHaveBeenCalledWith(
+    //             'Failure to edit survey',
+    //             'The existing survey could not be edited into the database'
+    //         );
+    //     });
+    // });
+    //
+    // describe('deleteSurvey$ effect', () => {
+    //     it('should dispatch the deleteSurveySuccess action on success', () => {
+    //         const action = outputFamilyActions.deleteSurvey({ survey: SURVEY });
+    //         const outcome = outputFamilyActions.deleteSurveySuccess({ survey: SURVEY});
+    //
+    //         actions = hot('-a', { a: action });
+    //         const response = cold('-a|', { a: SURVEY });
+    //         const expected = cold('--b', { b: outcome });
+    //         service.deleteSurvey = jest.fn(() => response);
+    //
+    //         expect(effects.deleteSurvey$).toBeObservable(expected);
+    //     });
+    //
+    //     it('should dispatch the deleteSurveyFail action on HTTP failure', () => {
+    //         const action = outputFamilyActions.deleteSurvey({ survey: SURVEY });
+    //         const error = new Error();
+    //         const outcome = outputFamilyActions.deleteSurveyFail();
+    //
+    //         actions = hot('-a', { a: action });
+    //         const response = cold('-#|', { }, error);
+    //         const expected = cold('--b', { b: outcome });
+    //         service.deleteSurvey = jest.fn(() => response);
+    //
+    //         expect(effects.deleteSurvey$).toBeObservable(expected);
+    //     });
+    // });
+    //
+    // describe('deleteSurveySuccess$ effect', () => {
+    //     it('should not dispatch', () => {
+    //         expect(metadata.deleteSurveySuccess$).toEqual(
+    //             expect.objectContaining({ dispatch: false })
+    //         );
+    //     });
+    //
+    //     it('should display a success notification', () => {
+    //         const toastrSpy = jest.spyOn(toastr, 'success');
+    //         const action = outputFamilyActions.deleteSurveySuccess({ survey: SURVEY });
+    //
+    //         actions = hot('a', { a: action });
+    //         const expected = cold('a', { a: action });
+    //
+    //         expect(effects.deleteSurveySuccess$).toBeObservable(expected);
+    //         expect(toastrSpy).toHaveBeenCalledTimes(1);
+    //         expect(toastrSpy).toHaveBeenCalledWith(
+    //             'Survey successfully deleted',
+    //             'The existing survey has been deleted'
+    //         );
+    //     });
+    // });
+    //
+    // describe('deleteSurveyFail$ effect', () => {
+    //     it('should not dispatch', () => {
+    //         expect(metadata.deleteSurveyFail$).toEqual(
+    //             expect.objectContaining({ dispatch: false })
+    //         );
+    //     });
+    //
+    //     it('should display an error notification', () => {
+    //         const spy = jest.spyOn(toastr, 'error');
+    //         const action = outputFamilyActions.deleteSurveyFail();
+    //
+    //         actions = hot('a', { a: action });
+    //         const expected = cold('a', { a: action });
+    //
+    //         expect(effects.deleteSurveyFail$).toBeObservable(expected);
+    //         expect(spy).toHaveBeenCalledTimes(1);
+    //         expect(spy).toHaveBeenCalledWith(
+    //             'Failure to delete survey',
+    //             'The existing survey could not be deleted from the database'
+    //         );
+    //     });
+    // });
+});
diff --git a/client/src/app/metamodel/effects/survey.effects.spec.ts b/client/src/app/metamodel/effects/survey.effects.spec.ts
index 456154a6267d4571da4ddb6e8e3ed051c83c24c5..13ac0bbbc52ec976db97c5330d8c6fa3bc46b9c2 100644
--- a/client/src/app/metamodel/effects/survey.effects.spec.ts
+++ b/client/src/app/metamodel/effects/survey.effects.spec.ts
@@ -5,8 +5,8 @@ import { provideMockActions } from '@ngrx/effects/testing';
 import { EffectsMetadata, getEffectsMetadata } from '@ngrx/effects';
 import { Observable } from 'rxjs';
 import { cold, hot } from 'jasmine-marbles';
-
 import { ToastrService } from 'ngx-toastr';
+
 import { SurveyEffects } from './survey.effects';
 import { SurveyService } from '../services/survey.service';
 import * as surveyActions from '../actions/survey.actions';
@@ -74,7 +74,7 @@ describe('[Metamodel][Effects] SurveyEffects', () => {
     describe('addSurvey$ effect', () => {
         it('should dispatch the addSurveySuccess action on success', () => {
             const action = surveyActions.addSurvey({ survey: SURVEY });
-            const outcome = surveyActions.addSurveySuccess({ survey: SURVEY});
+            const outcome = surveyActions.addSurveySuccess({ survey: SURVEY });
 
             actions = hot('-a', { a: action });
             const response = cold('-a|', { a: SURVEY });
@@ -150,7 +150,7 @@ describe('[Metamodel][Effects] SurveyEffects', () => {
     describe('editSurvey$ effect', () => {
         it('should dispatch the editSurveySuccess action on success', () => {
             const action = surveyActions.editSurvey({ survey: SURVEY });
-            const outcome = surveyActions.editSurveySuccess({ survey: SURVEY});
+            const outcome = surveyActions.editSurveySuccess({ survey: SURVEY });
 
             actions = hot('-a', { a: action });
             const response = cold('-a|', { a: SURVEY });
@@ -226,7 +226,7 @@ describe('[Metamodel][Effects] SurveyEffects', () => {
     describe('deleteSurvey$ effect', () => {
         it('should dispatch the deleteSurveySuccess action on success', () => {
             const action = surveyActions.deleteSurvey({ survey: SURVEY });
-            const outcome = surveyActions.deleteSurveySuccess({ survey: SURVEY});
+            const outcome = surveyActions.deleteSurveySuccess({ survey: SURVEY });
 
             actions = hot('-a', { a: action });
             const response = cold('-a|', { a: SURVEY });