(深度)单元测试中对象与引用的比较 (C#)

问题描述 投票:0回答:4

在单元测试(在 Visual Studio 2008 中)中,我想将一个大对象(准确地说是自定义类型列表)的内容与该对象的存储引用进行比较。目标是确保以后对代码的任何重构都会产生相同的对象内容。

废弃的想法: 第一个想法是序列化为 XML,然后比较硬编码字符串或文件内容。这将允许轻松找到任何差异。然而,由于我的类型在没有 hack 的情况下无法 XML 序列化,所以我必须找到另一个解决方案。我可以使用二进制序列化,但这将不再可读。

有一个简单而优雅的解决方案吗?

编辑:根据Marc Gravell的提议,我现在喜欢这样:

using (MemoryStream stream = new MemoryStream())
        {
            //create actual graph using only comparable properties
            List<NavigationResult> comparableActual = (from item in sparsed
                                                       select new NavigationResult
                                                       {
                                                           Direction = item.Direction,
                                                           /*...*/
                                                           VersionIndication = item.VersionIndication
                                                       }).ToList();

            (new BinaryFormatter()).Serialize(stream, comparableActual);
            string base64encodedActual = System.Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length);//base64 encoded binary representation of this                
            string base64encodedReference = @"AAEAAAD....";//this reference is the expected value
            Assert.AreEqual(base64encodedReference, base64encodedActual, "The comparable part of the sparsed set is not equal to the reference.");
        }

本质上,我首先选择可比较的属性,然后对图进行编码,然后将其与类似编码的参考进行比较。 编码可以以简单的方式进行深度比较。我使用 Base64 编码的原因是,我可以轻松地将引用存储在字符串变量中。

c# visual-studio unit-testing object comparison
4个回答
5
投票

我仍然倾向于使用序列化。但不必“知道”二进制文件,只需创建一个预期的图表并将其序列化即可。现在序列化“实际”图并比较字节。这只是为了告诉您存在差异;您需要检查才能找到什么,这很痛苦。 我会使用 hack 来进行 XML 比较。或者您可以使用反射来自动遍历对象属性(但这将遍历所有对象属性,还有一些您不希望遍历的属性)。


1
投票

我会让每个自定义类型继承IComparable,并提供相等方法,比较每个自定义类型,以及使主类ICompareble,然后你可以简单地比较这2个对象(如果运行单元测试时内存中有它们)如果没有,那么我建议序列化或定义您期望重构对象具有的常量。


1
投票

我可以想到 2 个尚未提及的选项来避免使用序列化:


0
投票

您可以使用 SHA256.HashData 等创建 HashCode,并将结果转换为 Base64 编码的字符串,并将其作为 const 存储在单元测试中:

    var hashBytes = SHA256.HashData(data); var base64EncodedString = Convert.ToBase64String(hashBytes);
  1. 您可以创建一个预期的对象图,然后使用 FluentAssertions nuget 包遍历该对象图。  我经常使用它来做同样的事情,发现它总是效果很好。 FluentAssertions 非常强大!
  2. var expectedModel = //create your expected object graph here actual.Should().BeEquivalentTo(expectedData, options => options.WithStrictOrdering());

  3. 参见:

https:// Fluentassertions.com/objectgraphs/

© www.soinside.com 2019 - 2024. All rights reserved.