You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用BinaryFormatter对自定义异常的序列化反序列化做单元测试?

替代BinaryFormatter测试自定义异常序列化的方案

StackOverflow上不少自定义异常类的单元测试教程都依赖BinaryFormatter做序列化/反序列化验证,但微软早已明确建议不再使用这个类。以下是原来基于BinaryFormatter的测试代码:

[TestMethod]
public void test()
{
    // Arrange
    const string TestMessage = "testMessage";
    var exception = new AbcException(TestMessage);
    using var stream = new MemoryStream();
    var formatter = new BinaryFormatter();

    // Act
    formatter.Serialize(stream, exception);
    stream.Position = 0; // Reset stream position

    var deserializedException = (AbcException)formatter.Deserialize(stream);

    // Assert
    Assert.AreEqual(TestMessage, deserializedException.Message);
}

下面提供两种安全且官方推荐的替代方案:

方案1:使用System.Text.Json(.NET Core/.NET 5+ 推荐)

System.Text.Json是.NET现代版本的默认序列化库,安全高效,无需额外依赖。测试代码如下:

[TestMethod]
public void TestAbcExceptionSerialization_WithJson()
{
    // Arrange
    const string TestMessage = "testMessage";
    var exception = new AbcException(TestMessage);

    // Act
    var jsonString = JsonSerializer.Serialize(exception);
    var deserializedException = JsonSerializer.Deserialize<AbcException>(jsonString);

    // Assert
    Assert.AreEqual(TestMessage, deserializedException.Message);
}

注意事项

  • 如果自定义异常包含额外的自定义属性,确保这些属性是公共的,或者通过[JsonPropertyName]特性标记,保证序列化/反序列化能正确识别。
  • 若需要处理InnerException这类可能存在循环引用的场景,可配置序列化选项:
    var options = new JsonSerializerOptions
    {
        ReferenceHandler = ReferenceHandler.IgnoreCycles,
        WriteIndented = true
    };
    var jsonString = JsonSerializer.Serialize(exception, options);
    

方案2:使用XmlSerializer(兼容旧.NET Framework)

如果需要兼容.NET Framework环境,XmlSerializer是另一个安全的选择:

[TestMethod]
public void TestAbcExceptionSerialization_WithXml()
{
    // Arrange
    const string TestMessage = "testMessage";
    var exception = new AbcException(TestMessage);
    var serializer = new XmlSerializer(typeof(AbcException));

    // Act
    using var stream = new MemoryStream();
    serializer.Serialize(stream, exception);
    stream.Position = 0;
    var deserializedException = (AbcException)serializer.Deserialize(stream);

    // Assert
    Assert.AreEqual(TestMessage, deserializedException.Message);
}

注意事项

  • XmlSerializer要求目标类必须有公共无参构造函数,如果你的自定义异常没有,需要补充一个,否则会序列化失败。

内容的提问来源于stack exchange,提问作者hardfork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:36:27