单元测试序列化有什么意义吗? [英] Is there any point Unit testing serialization?

查看:66
本文介绍了单元测试序列化有什么意义吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类可以序列化一组我想要进行单元测试的对象(使用 XML 序列化).

I have a class that serializes a set of objects (using XML serialization) that I want to unit test.

我的问题是感觉我将测试 XML 序列化的 .NET 实现,而不是任何有用的东西.我还有一个轻微的先有鸡还是先有蛋的场景,为了测试 Reader,我需要一个由 Writer 生成的文件来执行此操作.

My problem is it feels like I will be testing the .NET implementation of XML serialization, instead of anything useful. I also have a slight chicken and egg scenario where in order to test the Reader, I will need a file produced by the Writer to do so.

我认为我最终要寻求反馈的问题(有 3 个,但它们都相关)是:

I think the questions (there's 3 but they all relate) I'm ultimately looking for feedback on are:

  1. 是否可以在不使用 Reader 的情况下测试 Writer?
  2. 测试阅读器的最佳策略是什么(XML 文件?记录/回放模拟)?是否您真正要做的只是测试已反序列化的对象的属性值?
  3. 测试作者的最佳策略是什么!

Xml 序列化的背景信息

我没有使用架构,因此所有 XML 元素和属性都与对象的属性相匹配.由于没有架构,与在每个对象的属性中找到的标记/属性不匹配的标记/属性会被 XmlSerializer 简单地忽略(因此属性的值为 null 或默认值).这是一个例子

I'm not using a schema, so all XML elements and attributes match the objects' properties. As there is no schema, tags/attributes which do not match those found in properties of each object, are simply ignored by the XmlSerializer (so the property's value is null or default). Here is an example

<MyObject Height="300">
    <Name>Bob</Name>
    <Age>20</Age>
<MyObject>

将映射到

public class MyObject
{
  public string Name { get;set; }
  public int Age { get;set; }

  [XmlAttribute]
  public int Height { get;set; }
}

反之亦然.如果对象更改为下面的 XML 仍会成功反序列化,但 FirstName 将为空.

and visa versa. If the object changed to the below the XML would still deserialize succesfully, but FirstName would be blank.

public class MyObject
{
  public string FirstName { get;set; }
  public int Age { get;set; }

  [XmlAttribute]
  public int Height { get;set; }
}

无效的 XML 文件会正确反序列化,因此除非您对 MyObject 的值运行断言,否则单元测试将通过.

An invalid XML file would deserialize correctly, therefore the unit test would pass unless you ran assertions on the values of the MyObject.

推荐答案

我认为单元测试序列化必不可少如果您可以在版本之间读取数据至关重要.并且您必须使用已知良好"数据进行测试(即简单地在当前版本中写入数据然后再次读取是不够的).

I would argue that it is essential to unit test serialization if it is vitally important that you can read data between versions. And you must test with "known good" data (i.e. it isn't sufficient to simply write data in the current version and then read it again).

你提到你没有架构……为什么不生成一个?手动(不是很困难),或使用 xsd.exe.然后你有一些东西可以用作模板,你可以使用 XmlReader 验证这一点.目前,我正在用 xml 序列化做很多的工作,更新架构比担心我是否正确获取数据要容易得多.

You mention that you don't have a schema... why not generate one? Either by hand (it isn't very hard), or with xsd.exe. Then you have something to use as a template, and you can verify this just using XmlReader. I'm doing a lot of work with xml serialization at the moment, and it is a lot easier to update the schema than it is to worry about whether I'm getting the data right.

即使 XmlSerializer 也会变得复杂;特别是如果您涉及子类 ([XmlInclude])、自定义序列化 (IXmlSerializable) 或非默认 XmlSerializer 构造(在运行时传递额外的元数据)给演员).另一种可能性是创造性地使用 [XmlIngore][XmlAnyAttribute][XmlAnyElement];例如,您可能在版本 X 中支持(仅)往返的意外数据,但将其存储在版本 Y 中的已知属性中.

Even XmlSerializer can get complex; particularly if you involve subclasses ([XmlInclude]), custom serialization (IXmlSerializable), or non-default XmlSerializer construction (passing additional metadata at runtime to the ctor). Another possibility is creative use of [XmlIngore], [XmlAnyAttribute] or [XmlAnyElement]; for example you might support unexpected data for round-trip (only) in version X, but store it in a known property in version Y.

一般使用序列化:

原因很简单:你可以破解数据!你这样做有多糟糕取决于序列化程序;例如,使用 BinaryFormatter(我知道问题是 XmlSerializer),只需更改:

The reason is simple: you can break the data! How badly you do this depends on the serializer; for example, with BinaryFormatter (and I know the question is XmlSerializer), simply changing from:

public string Name {get;set;}

private string name;
public string Name {
    get {return name;}
    set {name = value; OnPropertyChanged("Name"); }
}

可能足以破坏序列化,作为字段名称已更改(并且 BinaryFormatter 喜欢字段).

could be enough to break serialization, as the field name has changed (and BinaryFormatter loves fields).

在其他情况下,您可能会意外重命名数据(即使在基于合约的序列化程序中,例如 XmlSerializer/DataContractSerializer).在这种情况下,您通常可以覆盖线路标识符(例如 [XmlAttribute("name")] 等),但检查这一点很重要!

There are other occasions when you might accidentally rename the data (even in contract-based serializers such as XmlSerializer / DataContractSerializer). In such cases you can usually override the wire identifiers (for example [XmlAttribute("name")] etc), but it is important to check this!

最终归结为:您可以读取旧数据是否重要?通常是;所以不要只是发货...证明你可以.

Ultimately, it comes down to: is it important that you can read old data? It usually is; so don't just ship it... prove that you can.

这篇关于单元测试序列化有什么意义吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆