【问题标题】:FluentAssertions - how make ShouldBeEquivalentTo compare empty and null as equalFluentAssertions - 如何让 ShouldBeEquivalentTo 比较空和空值相等
【发布时间】:2016-12-29 07:49:51
【问题描述】:

我正在使用 Fluent Assertion 库作为我对一些自定义序列化代码的单元测试的一部分,并且我正在寻找一种方法来强制 ShouldBeEquivalentTo 将 null 和空列表进行比较。

基本上,我的测试看起来像:

    [Test]
    public void Should_be_xxx()
    {
        ClassWithList one = new ClassWithList { Id = "ten", Items = null };

        string serialized = Serialize(one);
        ClassWithList two = Deserialize(serialized);

        two.ShouldBeEquivalentTo(one);
    }

然而,Deserialize 方法的特性之一是,如果输入数据中缺少集合类型,它会将反序列化类的属性设置为空列表,而不是 null。因此,非常简单,我最终会遇到在实例二中 Items = new List<string> 而不是 null 的情况。

显然,我可以在比较之前设置one.Items = new List<string>(),但实际上我有大量复杂的域对象,我在这些方法中断言,我正在寻找一个通用的解决方案。换句话说,有谁知道如何使以下测试通过:

    public class ClassWithList
    {
        public string Id { get; set; }
        public List<string> Items { get; set; }
    }

    [Test]
    public void Should_be_xxx()
    {
        ClassWithList one = new ClassWithList { Id = "ten", Items = null };
        ClassWithList two = new ClassWithList { Id = "ten", Items = new List<string>() };

        two.ShouldBeEquivalentTo(one);
    }

换句话说,我希望将以下测试应用于 X 类中的所有集合,作为比较等价性的一部分:

  if (subject.Items == null)
  {
     expected.Items.Should().BeEmpty();
  }
  else
  {
     expected.Items.Should().BeEquivalentTo(subject.Items);
  }

【问题讨论】:

    标签: c# fluent-assertions


    【解决方案1】:

    根据上面丹尼斯的信息,我能够通过以下实际代码解决这个问题:

        public class ClassWithList
        {
            public string Id { get; set; }
            public List<string> Items { get; set; }
            public List<ClassWithList> Nested { get; set; }
        }
    
        [TestClass]
        public class Test
        {
            [TestMethod]
            public void Should_compare_null_to_empty()
            {
                ClassWithList one = new ClassWithList { Id = "ten", Items = null, Nested = new List<ClassWithList> { new ClassWithList { Id = "a" } } };
                ClassWithList two = new ClassWithList { Id = "ten", Items = new List<string>(), Nested = new List<ClassWithList> { new ClassWithList { Id = "a", Items = new List<string>(), Nested = new List<ClassWithList> { } } } };
    
                two.ShouldBeEquivalentTo(one, opt => opt
                    .Using<IEnumerable>(CheckList)
                    .When(info => typeof(IEnumerable).IsAssignableFrom(info.CompileTimeType)));
            }
    
            private void CheckList(IAssertionContext<IEnumerable> a)
            {
                if (a.Expectation == null)
                {
                    a.Subject.Should().BeEmpty();
                }
                else
                {
                    a.Subject.ShouldBeEquivalentTo(a.Expectation, opt => opt
                        .Using<IEnumerable>(CheckList)
                        .When(info => typeof(IEnumerable).IsAssignableFrom(info.CompileTimeType)));
                }
            }
        }
    

    【讨论】:

      【解决方案2】:

      您必须实现自定义“IEquivalencyStep”或使用“options.Using(custom action).WhenTypeIs(predicate)”。

      【讨论】:

        【解决方案3】:

        创建IAssertionRule

        public class EnumerableNullEmptyEquivalenceRule : IAssertionRule
        {
            public bool AssertEquality(IEquivalencyValidationContext context)
            {
                // not applicable - return false
                if (!typeof(IEnumerable).IsAssignableFrom(context.SelectedMemberInfo.MemberType)) return false;
        
                return context.Expectation == null && ((IEnumerable)context.Subject).IsNullOrEmpty();
            }
        }
        

        然后申请您的BeEquivalentTo 电话:

        actual.Should().BeEquivalentTo(expected, opt => opt.Using(new EnumerableNullEmptyEquivalenceRule()));
        

        【讨论】:

          猜你喜欢
          • 2014-08-01
          • 2010-11-20
          • 2021-12-17
          • 2013-04-15
          • 1970-01-01
          • 1970-01-01
          • 2012-11-21
          • 1970-01-01
          • 2022-07-02
          相关资源
          最近更新 更多