gpt4 book ai didi

c# - 使用 FluentAssertions 比较包含不同类型的两个字典集合

转载 作者:行者123 更新时间:2023-11-30 23:03:37 25 4
gpt4 key购买 nike

从我们的数据库中,我们查询放在 ExpandoObject 类型的动态对象集合中的记录集。实现 IDictionary<string, object>在田野上。这些是实际值。

从我们的 SpecFlow BDD 测试中,我们得到了一组实现 IDictionary<string, string> 的 TableRows .这些是我们的预期值。

使用 FluentAssertions,我们想用 actual.Should().BeEquivalentTo(expected) 测试整个集合的等效性.不幸的是,这行不通,因为当实际值不是 string 类型时类型不匹配.

我们可以使用 actual.Should().BeEquivalentTo(expected, options => options.WithAutoConversion()) , 但这将使整个实际集合成为 IDictionary<string, string> 的集合这对于比较日期没有用。

我组装了一个将显示相同问题的测试用例:

var expected = new List<Dictionary<string, string>>();
expected.Add(new Dictionary<string, string>
{
{"Name", "Moon Inc."},
{"Number", "42"},
{"Date", "2018-12-31"}
});

var actual = new List<ExpandoObject>();
dynamic eo = new ExpandoObject();
eo.Name = "Moon Inc.";
eo.Number = 42;
eo.Date = new DateTime(2018, 12, 31);

actual.Add(eo);

actual.Should().BeEquivalentTo(expected, options => options);
/*
This throws:
NUnit.Framework.AssertionException:
Expected item[0][Number] to be System.String, but found System.Int32.
Expected item[0][Date] to be System.String, but found System.DateTime.
*/

actual.Should().BeEquivalentTo(expected, options => options.WithAutoConversion());
/*
This throws:
NUnit.Framework.AssertionException:
Expected item[0][Date] to be "2018-12-31" with a length of 10,
but "31-12-2018 0:00:00" has a length of 18.
/*

我尝试在如下使用方法中使接收类型动态化:

actual.Should().BeEquivalentTo(expected, options => options
.Using<dynamic>(ctx => ctx.Subject.Should().Be(ctx.Expectation)).WhenTypeIs<DateTime>()
.Using<dynamic>(ctx => ctx.Subject.Should().Be(ctx.Expectation)).WhenTypeIs<int>());

/*
NUnit.Framework.AssertionException:
Expected item[0][Number] to be System.String, but found System.Int32.
Expected item[0][Date] to be System.String, but found System.DateTime.
*/

将双方解析为 DateTime并且使用自动转换也不起作用,因为 actual类型不被视为 DateTime但作为 string :

actual.Should().BeEquivalentTo(expected, options => options
.Using<dynamic>(
ctx =>
DateTime.ParseExact(ctx.Subject, "yyy-MM-dd", CultureInfo.InvariantCulture)
.Should().Be(DateTime.ParseExact(ctx.Expectation, "yyy-MM-dd", CultureInfo.InvariantCulture)))
.WhenTypeIs<DateTime>()
.WithAutoConversion());

/*
NUnit.Framework.AssertionException:
Expected item[0][Date] to be "2018-12-31" with a length of 10,
but "31-12-2018 0:00:00" has a length of 18.
*/

FluentAssertions 有什么方法可以实现这一点吗?

最佳答案

如果没有其他帮助,您可以像这样实现自定义 IEquivalencyStep:

class WeakDateEquivalencyStep : IEquivalencyStep {
public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config) {
if (context.IsRoot)
return false;
// handles situations when subject is date
// but expectation is string
return context.Subject is DateTime && context.Expectation is string;
}

public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) {
DateTime exp;
// we know that expection is string here
if (!DateTime.TryParse((string) context.Expectation, CultureInfo.InvariantCulture, DateTimeStyles.None, out exp)) {
// do something, your spec is invalid
throw new Exception($"Value {context.Expectation} does not represent valid date time");
}

context.Subject.Should().Be(exp, context.Because, context.BecauseArgs);
return true;
}
}

然后

actual.Should().BeEquivalentTo(expected, options => 
options.Using(new WeakDateEquivalencyStep()).WithAutoConversion());

关于c# - 使用 FluentAssertions 比较包含不同类型的两个字典集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49850604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com