Fluent Assertions 能否对 IEnumerable<string> 使用不区分字符串的比较?

Posted

技术标签:

【中文标题】Fluent Assertions 能否对 IEnumerable<string> 使用不区分字符串的比较?【英文标题】:Can Fluent Assertions use a string-insensitive comparison for IEnumerable<string>? 【发布时间】:2012-04-10 06:46:32 【问题描述】:

我有一对列表,我正在尝试使用 Fluent Assertions 进行比较。我可以轻松编写比较代码,但我想使用 Fluent Assertions 以便我可以找到出现在测试失败消息中的原因。

到目前为止,我所看到的一切似乎都在使用默认的 Object.Equals 比较,它区分大小写。我似乎无法将 IComparer 传递给 Equal 或 Contains 方法,还有其他方法吗?

[TestMethod()]
public void foo()

  var actual = new List<string>  "ONE", "TWO", "THREE", "FOUR" ;
  var expected = new List<string>  "One", "Two", "Three", "Four" ;

  actual.Should().Equal(expected);

【问题讨论】:

【参考方案1】:

在 Fluent Assertions 的后续版本中,可以使用以下内容:

stringValue.Should().BeEquivalentTo(stringToCompare);

元数据摘要

断言一个字符串与另一个字符串完全相同,包括任何 前导或尾随空格,大小写除外

FluentAssertions 2.2.0.0

在我使用的版本中有效。

【讨论】:

【参考方案2】:

我们可以在 Equal() 方法中添加一个可选的 lambda 表达式。然后,你可以做类似

[TestMethod()] 
public void foo() 
 
   var actual = new List<string>  "ONE", "TWO", "THREE", "FOUR" ; 
   var expected = new List<string>  "One", "Two", "Three", "Four" ; 

  actual.Should().Equal(expected, 
    (o1, o2) => string.Compare(o1, o2, StringComparison.InvariantCultureIgnoreCase))
 

IComparer 也是可能的,但我认为 Equal() 的默认行为的偶尔例外不会保证额外的自定义编写类。事实上,单独的 IComparer 可能会掩盖测试的意图。让我知道你们认为最好的解决方案,以便我可以将其作为 Codeplex 1.8.0 版的问题添加。

【讨论】:

这正是我想要的。我现在将使用下面的一种解决方法,我会密切关注下一个版本。 提议的解决方案现已在主干中实施,并将成为即将发布的 2.0.0 版本的一部分。 现在处于公测阶段fluentassertions.codeplex.com/releases/view/82423【参考方案3】:

通过一个(或两个)扩展方法添加一个新的 Fluent 断言怎么样?我编写了代码以将.EqualInsensitively(...) 添加到字符串集合的可用流利断言中。

我已将实现此的代码放在an external pastebin 上,因为它有点长,而且 MS-PL 可能与 CC-Wiki 不兼容。

使用这样的东西:

private static void Main()

    var mylist = new List<string> "abc", "DEF", "GHI";
    mylist.Should().EqualInsensitively(new[] "AbC", "def", "GHI")
      .And.NotContain(string.Empty); //Emaple of chaining

【讨论】:

pastebin 链接 404s【参考方案4】:

您可以自己为IEnumerable&lt;string&gt; 编写扩展方法(这就是我做这些事情的方式),而且我认为某些单元测试框架已经这样做了(FSUnit AFAIK)

这是一个简单的例子(你可以改进很多 - 但它应该这样做)

public static AssertEqualSetCaseInsensitive(this IEnumerable<string> actual, IEnumerable<string> expected)

   if (actual.Count() != expected.Count())
      Assert.Fail("not same number of elements");

   if (!actual.All(a => expected.Any(e => e.ToLower() == a.ToLower()))
      Assert.Fail("not same sets");

像这样使用

actual.AssertEqualSetCaseInsensitive(expected);

【讨论】:

"我可以轻松编写比较代码,但我想使用 Fluent Assertions" 如果我必须编写代码,这可能是我的做法,但理想情况下,有人会向我展示一些我在库中还没有见过的方法。

以上是关于Fluent Assertions 能否对 IEnumerable<string> 使用不区分字符串的比较?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Fluent Assertions 引发异常?

使用 Fluent Assertions 库的多个断言

Fluent Assertions Should().BeEquivalentTo 只有私有字段

Fluent Assertions ShouldBeEquivalentTo 总是以不同的属性传递

Fluent Assertions:大致比较两个 2D 矩形阵列

ShouldBeEquivalentTo 的 C# Fluent Assertions 全局选项