diff --git a/ee/app/assets/javascripts/requirements/components/requirements_root.vue b/ee/app/assets/javascripts/requirements/components/requirements_root.vue
index 48973d4970481c11d7719a824142b1f390ee5f13..9cd5106394dc503266334dcde30cb607d9dc3c24 100644
--- a/ee/app/assets/javascripts/requirements/components/requirements_root.vue
+++ b/ee/app/assets/javascripts/requirements/components/requirements_root.vue
@@ -725,6 +725,7 @@ export default {
       @drawer-close="handleNewRequirementCancel"
     />
     <requirement-edit-form
+      data-testid="edit-form"
       :drawer-open="showRequirementViewDrawer"
       :requirement="editedRequirement"
       :enable-requirement-edit="enableRequirementEdit"
diff --git a/ee/spec/frontend/requirements/components/requirements_root_spec.js b/ee/spec/frontend/requirements/components/requirements_root_spec.js
index add1e30b255db2e4a0d54364eda1b8a0b5a4da54..9459db33b77d5729d68b21a5a12edf14c82086b6 100644
--- a/ee/spec/frontend/requirements/components/requirements_root_spec.js
+++ b/ee/spec/frontend/requirements/components/requirements_root_spec.js
@@ -1,18 +1,27 @@
-import { GlPagination } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { GlPagination, GlIcon } from '@gitlab/ui';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import VueApollo from 'vue-apollo';
 
 import RequirementItem from 'ee/requirements/components/requirement_item.vue';
+import RequirementStatusBadge from 'ee/requirements/components/requirement_status_badge.vue';
 import RequirementsEmptyState from 'ee/requirements/components/requirements_empty_state.vue';
 import RequirementsLoading from 'ee/requirements/components/requirements_loading.vue';
 import RequirementsRoot from 'ee/requirements/components/requirements_root.vue';
 import RequirementsTabs from 'ee/requirements/components/requirements_tabs.vue';
 
+import { TestReportStatus } from 'ee/requirements/constants';
 import createRequirement from 'ee/requirements/queries/createRequirement.mutation.graphql';
 import exportRequirement from 'ee/requirements/queries/exportRequirements.mutation.graphql';
+
+import projectRequirements from 'ee/requirements/queries/projectRequirements.query.graphql';
+import projectRequirementsCount from 'ee/requirements/queries/projectRequirementsCount.query.graphql';
 import updateRequirement from 'ee/requirements/queries/updateRequirement.mutation.graphql';
+import createMockApollo from 'helpers/mock_apollo_helper';
 
 import { TEST_HOST } from 'helpers/test_constants';
 import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
+import waitForPromises from 'helpers/wait_for_promises';
 import createFlash from '~/flash';
 import FilteredSearchBarRoot from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
 
@@ -24,12 +33,19 @@ import {
   mockFilters,
   mockAuthorToken,
   mockStatusToken,
+  mockInitialRequirementCounts,
+  mockProjectRequirementCounts,
+  mockProjectRequirements,
+  mockUpdateRequirementTitle,
+  mockUpdateRequirementToFailed,
+  mockProjectRequirementPassed,
 } from '../mock_data';
 
 jest.mock('ee/requirements/constants', () => ({
   DEFAULT_PAGE_SIZE: 2,
   FilterState: jest.requireActual('ee/requirements/constants').FilterState,
   AvailableSortOptions: jest.requireActual('ee/requirements/constants').AvailableSortOptions,
+  TestReportStatus: jest.requireActual('ee/requirements/constants').TestReportStatus,
 }));
 
 jest.mock('~/flash');
@@ -38,29 +54,25 @@ const $toast = {
   show: jest.fn(),
 };
 
-const createComponent = ({
-  projectPath = 'gitlab-org/gitlab-shell',
-  initialFilterBy = FilterState.opened,
-  initialRequirementsCount = mockRequirementsCount,
-  showCreateRequirement = false,
-  emptyStatePath = '/assets/illustrations/empty-state/requirements.svg',
-  loading = false,
-  canCreateRequirement = true,
-  requirementsWebUrl = '/gitlab-org/gitlab-shell/-/requirements',
-  importCsvPath = '/gitlab-org/gitlab-shell/-/requirements/import_csv',
-  currentUserEmail = 'admin@example.com',
-} = {}) =>
+const localVue = createLocalVue();
+
+const defaultProps = {
+  projectPath: 'gitlab-org/gitlab-shell',
+  initialFilterBy: FilterState.opened,
+  initialRequirementsCount: mockRequirementsCount,
+  showCreateRequirement: false,
+  emptyStatePath: '/assets/illustrations/empty-state/requirements.svg',
+  canCreateRequirement: true,
+  requirementsWebUrl: '/gitlab-org/gitlab-shell/-/requirements',
+  importCsvPath: '/gitlab-org/gitlab-shell/-/requirements/import_csv',
+  currentUserEmail: 'admin@example.com',
+};
+
+const createComponent = ({ props = {}, loading = false } = {}) =>
   shallowMount(RequirementsRoot, {
     propsData: {
-      projectPath,
-      initialFilterBy,
-      initialRequirementsCount,
-      showCreateRequirement,
-      emptyStatePath,
-      canCreateRequirement,
-      requirementsWebUrl,
-      importCsvPath,
-      currentUserEmail,
+      ...defaultProps,
+      ...props,
     },
     mocks: {
       $apollo: {
@@ -72,7 +84,7 @@ const createComponent = ({
             refetch: jest.fn(),
           },
           requirementsCount: {
-            ...initialRequirementsCount,
+            ...defaultProps.initialRequirementsCount,
             refetch: jest.fn(),
           },
         },
@@ -82,10 +94,44 @@ const createComponent = ({
     },
   });
 
+const createComponentWithApollo = ({ props = {}, requestHandlers } = {}) => {
+  localVue.use(VueApollo);
+
+  const mockApollo = createMockApollo(
+    requestHandlers,
+    {},
+    {
+      dataIdFromObject: (object) =>
+        // eslint-disable-next-line no-underscore-dangle
+        object.__typename === 'Requirement' ? object.iid : defaultDataIdFromObject(object),
+    },
+  );
+
+  return shallowMount(RequirementsRoot, {
+    localVue,
+    apolloProvider: mockApollo,
+    propsData: {
+      ...defaultProps,
+      ...props,
+    },
+    mocks: {
+      $toast,
+    },
+    stubs: {
+      RequirementItem,
+      RequirementStatusBadge,
+      GlIcon,
+    },
+  });
+};
+
 describe('RequirementsRoot', () => {
   let wrapper;
   let trackingSpy;
 
+  const findRequirementEditForm = () => wrapper.find("[data-testid='edit-form']");
+  const findFailedStatusIcon = () => wrapper.find("[data-testid='status_failed-icon']");
+
   beforeEach(() => {
     wrapper = createComponent();
     trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
@@ -427,51 +473,6 @@ describe('RequirementsRoot', () => {
         );
       });
 
-      describe('when `lastTestReportState` is included in object param', () => {
-        beforeEach(() => {
-          jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdateMutationResult);
-        });
-
-        it('calls `$apollo.mutate` with `lastTestReportState` when it is not null', () => {
-          wrapper.vm.updateRequirement({
-            iid: '1',
-            lastTestReportState: 'PASSED',
-          });
-
-          expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith(
-            expect.objectContaining({
-              mutation: updateRequirement,
-              variables: {
-                updateRequirementInput: {
-                  projectPath: 'gitlab-org/gitlab-shell',
-                  iid: '1',
-                  lastTestReportState: 'PASSED',
-                },
-              },
-            }),
-          );
-        });
-
-        it('calls `$apollo.mutate` without `lastTestReportState` when it is null', () => {
-          wrapper.vm.updateRequirement({
-            iid: '1',
-            lastTestReportState: null,
-          });
-
-          expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith(
-            expect.objectContaining({
-              mutation: updateRequirement,
-              variables: {
-                updateRequirementInput: {
-                  projectPath: 'gitlab-org/gitlab-shell',
-                  iid: '1',
-                },
-              },
-            }),
-          );
-        });
-      });
-
       it('calls `createFlash` with provided `errorFlashMessage` param when request fails', () => {
         jest.spyOn(wrapper.vm.$apollo, 'mutate').mockRejectedValue(new Error({}));
 
@@ -1025,4 +1026,103 @@ describe('RequirementsRoot', () => {
       });
     });
   });
+
+  describe('with apollo mock', () => {
+    describe('when requirement is edited', () => {
+      let updateRequirementSpy;
+
+      describe('when user changes the requirement\'s status to "FAILED" from "SUCCESS"', () => {
+        const editRequirementToFailed = () => {
+          findRequirementEditForm().vm.$emit('save', {
+            description: mockProjectRequirementPassed.description,
+            iid: mockProjectRequirementPassed.iid,
+            title: mockProjectRequirementPassed.title,
+            lastTestReportState: TestReportStatus.Failed,
+          });
+        };
+
+        beforeEach(() => {
+          updateRequirementSpy = jest.fn().mockResolvedValue(mockUpdateRequirementToFailed);
+
+          const requestHandlers = [
+            [projectRequirements, jest.fn().mockResolvedValue(mockProjectRequirements)],
+            [projectRequirementsCount, jest.fn().mockResolvedValue(mockProjectRequirementCounts)],
+            [updateRequirement, updateRequirementSpy],
+          ];
+
+          wrapper = createComponentWithApollo({
+            props: { initialRequirementsCount: mockInitialRequirementCounts },
+            requestHandlers,
+          });
+        });
+
+        it('calls `updateRequirement` mutation with correct parameters', () => {
+          editRequirementToFailed();
+
+          expect(updateRequirementSpy).toHaveBeenCalledWith({
+            updateRequirementInput: {
+              projectPath: 'gitlab-org/gitlab-shell',
+              iid: mockProjectRequirementPassed.iid,
+              lastTestReportState: TestReportStatus.Failed,
+              title: mockProjectRequirementPassed.title,
+            },
+          });
+        });
+
+        it('renders a failed badge after the update', async () => {
+          expect(findFailedStatusIcon().exists()).toBe(false);
+
+          editRequirementToFailed();
+          await waitForPromises();
+
+          expect(findFailedStatusIcon().exists()).toBe(true);
+        });
+      });
+
+      describe('when user changes the title of a requirement', () => {
+        const editRequirementTitle = () => {
+          findRequirementEditForm().vm.$emit('save', {
+            description: mockProjectRequirementPassed.description,
+            iid: mockProjectRequirementPassed.iid,
+            title: 'edited title',
+            lastTestReportState: null,
+          });
+        };
+
+        beforeEach(async () => {
+          updateRequirementSpy = jest.fn().mockResolvedValue(mockUpdateRequirementTitle);
+
+          const requestHandlers = [
+            [projectRequirements, jest.fn().mockResolvedValueOnce(mockProjectRequirements)],
+            [projectRequirementsCount, jest.fn().mockResolvedValue(mockProjectRequirementCounts)],
+            [updateRequirement, updateRequirementSpy],
+          ];
+
+          wrapper = createComponentWithApollo({
+            props: { initialRequirementsCount: mockInitialRequirementCounts },
+            requestHandlers,
+          });
+        });
+
+        it('calls `updateRequirement` mutation with correct parameters without `lastTestReport`', () => {
+          editRequirementTitle();
+
+          expect(updateRequirementSpy).toHaveBeenCalledWith({
+            updateRequirementInput: {
+              projectPath: 'gitlab-org/gitlab-shell',
+              iid: mockProjectRequirementPassed.iid,
+              title: 'edited title',
+            },
+          });
+        });
+
+        it('renders the edited title', async () => {
+          editRequirementTitle();
+          await waitForPromises();
+
+          expect(wrapper.find('.issue-title-text').text()).toContain('edited title');
+        });
+      });
+    });
+  });
 });
diff --git a/ee/spec/frontend/requirements/mock_data.js b/ee/spec/frontend/requirements/mock_data.js
index de3b2736448612f6b51c8c6c066fd95a804fd6f6..f0141e8f1d55c2b87164d5c183cfeb6e78df8012 100644
--- a/ee/spec/frontend/requirements/mock_data.js
+++ b/ee/spec/frontend/requirements/mock_data.js
@@ -174,3 +174,136 @@ export const mockStatusToken = {
   token: StatusToken,
   operators: [{ value: '=', description: 'is', default: 'true' }],
 };
+
+/* 
+  Mock data used for testing with mock apollo client
+*/
+
+export const mockInitialRequirementCounts = {
+  ARCHIVED: 0,
+  OPENED: 1,
+  ALL: 1,
+};
+
+export const mockProjectRequirementCounts = {
+  data: {
+    project: {
+      requirementStatesCount: {
+        opened: mockInitialRequirementCounts.OPENED,
+        archived: mockInitialRequirementCounts.ARCHIVED,
+        __typename: 'RequirementStatesCount',
+      },
+      __typename: 'Project',
+    },
+  },
+};
+
+const mockUser = {
+  ...mockAuthor,
+  id: 'gid://gitlab/User/1',
+  __typename: 'User',
+};
+
+export const mockTestReportConnectionPassed = {
+  nodes: [mockTestReport],
+  __typename: 'TestReportConnection',
+};
+
+export const mockTestReportConnectionFailed = {
+  nodes: [mockTestReportFailed],
+  __typename: 'TestReportConnection',
+};
+
+export const mockEmptyTestReportConnection = {
+  nodes: [],
+  __typename: 'TestReportConnection',
+};
+
+const projectRequirementBase = {
+  __typename: 'Requirement',
+  iid: '1',
+  title: 'Requirement 1',
+  titleHtml: 'Requirement 1',
+  description: '',
+  descriptionHtml: '',
+  createdAt: '2021-03-15T05:24:32Z',
+  updatedAt: '2021-03-15T05:24:32Z',
+  state: 'OPENED',
+  userPermissions: {
+    updateRequirement: true,
+    adminRequirement: true,
+    __typename: 'RequirementPermissions',
+  },
+  author: {
+    ...mockUser,
+  },
+};
+
+export const mockProjectRequirementFailed = {
+  ...projectRequirementBase,
+  lastTestReportState: 'FAILED',
+  lastTestReportManuallyCreated: true,
+  testReports: {
+    ...mockTestReportConnectionFailed,
+  },
+};
+
+export const mockProjectRequirementPassed = {
+  ...projectRequirementBase,
+  lastTestReportState: 'PASSED',
+  lastTestReportManuallyCreated: true,
+  testReports: {
+    ...mockTestReportConnectionPassed,
+  },
+};
+
+export const mockUpdateRequirementTitle = {
+  data: {
+    updateRequirement: {
+      clientMutationId: null,
+      errors: [],
+      requirement: {
+        ...mockProjectRequirementPassed,
+        title: 'edited title',
+      },
+      __typename: 'UpdateRequirementPayload',
+    },
+  },
+};
+
+export const mockUpdateRequirementToFailed = {
+  data: {
+    updateRequirement: {
+      clientMutationId: null,
+      errors: [],
+      requirement: {
+        ...mockProjectRequirementFailed,
+      },
+      __typename: 'UpdateRequirementPayload',
+    },
+  },
+};
+
+const mockRequirementConnection = {
+  nodes: [],
+  pageInfo: {
+    __typename: 'PageInfo',
+    hasNextPage: false,
+    hasPreviousPage: false,
+    startCursor: 'eyJpZCI6',
+    endCursor: 'eyJpZCI6I',
+  },
+  __typename: 'RequirementConnection',
+};
+
+export const mockProjectRequirements = {
+  data: {
+    project: {
+      requirements: {
+        ...mockRequirementConnection,
+        nodes: [{ ...mockProjectRequirementPassed }],
+      },
+      __typename: 'Project',
+    },
+  },
+};