diff --git a/gems/gitlab-backup-cli/lib/gitlab/backup/cli/metadata/serializer.rb b/gems/gitlab-backup-cli/lib/gitlab/backup/cli/metadata/serializer.rb
index 9cdc2d22f19db548fd9018064aaf45529395ca7b..e0351c860ec0cf007cea8b4c74e8603f80f3ef80 100644
--- a/gems/gitlab-backup-cli/lib/gitlab/backup/cli/metadata/serializer.rb
+++ b/gems/gitlab-backup-cli/lib/gitlab/backup/cli/metadata/serializer.rb
@@ -12,8 +12,8 @@ module Serializer
           # JSON primitive type before serializing
           #
           # @param [Symbol] type
-          # @param [Object] value
-          # @return [Object] the converted JSON primitive value
+          # @param [String|Time|Integer] value
+          # @return [Integer, String] the converted JSON primitive value
           def serialize_value(type:, value:)
             return value if value.nil?
 
@@ -22,21 +22,31 @@ def serialize_value(type:, value:)
             when :time then serialize_time(value)
             when :integer then serialize_integer(value)
             else
-              raise NameError, "Unknown data type key #{type.inspect} provided when serializing backup metadata"
+              raise ArgumentError, "Unknown data type key #{type.inspect} provided when serializing backup metadata"
             end
           end
 
+          # Serialize the integer value
+          #
+          # @return [Integer]
           def serialize_integer(value)
             return value if value.nil?
 
             value.to_i
           end
 
+          # Serialize the String value
+          #
+          # @return [String]
           def serialize_string(value)
             value.to_s
           end
 
+          # Serialize the Time value using ISO8601 format
+          #
+          # @return [String]
           def serialize_time(value)
+            return value if value.nil?
             raise ArgumentError unless value.is_a?(Time)
 
             # ensures string values and nil are properly cast to Time objects
diff --git a/gems/gitlab-backup-cli/spec/gitlab/backup/cli/metadata/serializer_spec.rb b/gems/gitlab-backup-cli/spec/gitlab/backup/cli/metadata/serializer_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..79869fbd7cdefde1b4ac75d644b404184c376884
--- /dev/null
+++ b/gems/gitlab-backup-cli/spec/gitlab/backup/cli/metadata/serializer_spec.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+RSpec.describe Gitlab::Backup::Cli::Metadata::Serializer do
+  subject(:serializer) { described_class }
+
+  describe '.serialize_value' do
+    context 'when type is :integer' do
+      it 'delegates to .serialize_integer' do
+        expect(serializer).to receive(:serialize_integer).with(123)
+
+        serializer.serialize_value(type: :integer, value: 123)
+      end
+    end
+
+    context 'when type is :string' do
+      it 'delegates to .serialize_string' do
+        expect(serializer).to receive(:serialize_string).with('content')
+
+        serializer.serialize_value(type: :string, value: 'content')
+      end
+    end
+
+    context 'when type is :time' do
+      it 'delegates to .serialize_time' do
+        time = Time.now
+
+        expect(serializer).to receive(:serialize_time).with(time)
+        serializer.serialize_value(type: :time, value: time)
+      end
+    end
+
+    context 'when type is something else' do
+      it 'raises an error' do
+        expect { serializer.serialize_value(type: :something, value: '123') }.to raise_error(ArgumentError)
+      end
+    end
+  end
+
+  describe '.serialize_integer' do
+    context 'when value is not nil' do
+      it 'returns an integer' do
+        expect(serializer.serialize_integer(123)).to eq(123)
+        expect(serializer.serialize_integer('123')).to eq(123)
+      end
+    end
+
+    context 'when value is nil' do
+      it 'returns nil' do
+        expect(serializer.serialize_integer(nil)).to be_nil
+      end
+    end
+  end
+
+  describe '.serialize_string' do
+    it 'returns an string' do
+      expect(serializer.serialize_string(123)).to eq('123')
+      expect(serializer.serialize_string('content')).to eq('content')
+      expect(serializer.serialize_string(nil)).to eq('')
+    end
+  end
+
+  describe '.serialize_time' do
+    context 'when value is a Time' do
+      it 'returns a string in ISO8601 format' do
+        time = Time.new(2024, 1, 1, 0, 0, 0, 'UTC')
+
+        expect(serializer.serialize_time(time)).to eq('2024-01-01T00:00:00Z')
+      end
+    end
+
+    context 'when value is nil' do
+      it 'returns nil' do
+        expect(serializer.serialize_time(nil)).to be_nil
+      end
+    end
+
+    context 'when value is not a Time' do
+      it 'raises an error' do
+        expect { serializer.serialize_time('not a Time') }.to raise_error(ArgumentError)
+      end
+    end
+  end
+end