断言结合收集和财产的断言

断言结合收集和财产的断言

本文介绍了如何用流利的-断言结合收集和财产的断言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想结合流利断言的集合断言和属性断言,例如断言两个的IEnumerable 的使用属性由属性(可能是嵌套)比较(即结构性平等,函数式语言的说法)两两相等。



具体的例子:

  VAR DIC =新词典< INT,串>( ){{1,喜},{2,再见}}; 
VAR实际= dic.ToSelectListItems(0).OrderBy(SI => si.Text);

VAR预期=新的List< SelectListItem>(){
新SelectListItem(){选择=假,文本=再见,值=2},
新SelectListItem(){选择=假,文本=喜,值=1}
};

下面我写了一个扩展方法 ToSelectListItems 的转换一个词典的IEnumerable SelectListItem S(从ASP.NET MVC)。我想断言,实际有望是结构平等,并指出引用类型 SelectListItem 不覆盖等于和因此默认使用引用相等。



更新



目前使用下面的手卷解决方案,仍然希望更好的东西内置到FluentAssertions:

 公共静态无效ShouldBeStructurallyEqualTo< T,U>(这个IEnumerable的< T>实际,IEnumerable的< U>预期){
actual.Should()HaveCount (expected.Count());
actual.Zip(预期).ForEach(对= GT; pair.Item1.ShouldHave()AllProperties()IncludingNestedObjects()EqualTo(pair.Item2)。);
}



(注:邮编这里是使用 Tuple.Create 作为默认的投影)

$ b $我自己的的IEnumerable 延伸b

更新2



下面是两个很小的例子:

 公共类FooBar的{
公共字符串美孚{搞定;组; }
公众诠释吧{搞定;组; }
}

公共类识别TestClass {
[测试]
公共无效MinimalExample(){
名单,LT; FooBar的> enumerable1 =新的List<&FooBar的GT;(){新FooBar的(){美孚=X,酒吧= 1},新的FooBar的(){美孚=Y,酒吧= 2}};
名单,LT; FooBar的> enumerable2 =新的List<&FooBar的GT;(){新FooBar的(){美孚=X,酒吧= 1},新的FooBar的(){美孚=Y,酒吧= 2}}; 。

enumerable1.ShouldHave()SharedProperties()IncludingNestedObjects()EqualTo(enumerable2);

//测试TestClass.MinimalExample'失败:System.Reflection.TargetParameterCountException:参数数量不匹配。
//在System.Reflection.RuntimeMethodInfo.Invoke(obj对象,的BindingFlags invokeAttr,粘结剂粘合,对象[]参数,CultureInfo的文化,布尔skipVisibilityChecks)在System.Reflection.RuntimeMethodInfo.Invoke
//( obj对象,的BindingFlags invokeAttr,粘合剂粘合,在System.Reflection.RuntimePropertyInfo.GetValue(obj对象,的BindingFlags invokeAttr,宾德Binder对象[]参数,CultureInfo的文化)
//,对象[]索引,CultureInfo的文化)
//在System.Reflection.RuntimePropertyInfo.GetValue(obj对象,对象[]指数)
//在FluentAssertions.Assertions.PropertyEqualityValidator.AssertSelectedPropertiesAreEqual(对象主体,客体预期)
//在FluentAssertions.Assertions.PropertyEqualityValidator.Validate(UniqueObjectTracker跟踪器,串parentPropertyName)
//在FluentAssertions.Assertions.PropertyEqualityValidator.Validate()
//在FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(对象otherObject, reason字符串,对象[] reasonArgs)
//在FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(对象otherObject)
// MiscAssertions.cs(32,0):在TestClass.MinimalExample()
}

[测试]
公共无效MinimalExample2(){
IEnumerable的<&FooBar的GT; enumerable1 =(新的List< FooBar的>(){新FooBar的(){美孚=X,酒吧= 1},新的FooBar的(){美孚=Y,酒吧= 2}})演员LT; FooBar的>( );
FooBar的[] enumerable2 =新[] {新FooBar的(){美孚=X,酒吧= 1},新的FooBar的(){美孚=Y,酒吧= 2}}; 。

enumerable1.ShouldHave()SharedProperties()IncludingNestedObjects()EqualTo(enumerable2);

//测试TestClass.MinimalExample2'失败信息:System.InvalidOperationException:请指定某些属性在比较中包括。
//在FluentAssertions.Assertions.PropertyEqualityValidator.Validate(UniqueObjectTracker跟踪器,串parentPropertyName)
//在FluentAssertions.Assertions.PropertyEqualityValidator.Validate()
//在FluentAssertions.Assertions.PropertyAssertions` 1.EqualTo(对象otherObject,字符串原因,对象[] reasonArgs)在FluentAssertions.Assertions.PropertyAssertions`1.EqualTo
//(对象otherObject)
// MiscAssertions.cs(52.0):在TestClass.MinimalExample2()
}
}


解决方案

我在流利的断言加入到主分支为您的方案的支持。这将是下一版本的一部分,但它可能会带我们一两个月来accumalate足够的变化,以保证另一个版本。如果你愿意,你可以抓住源构建和运行release.bat建立一个中间版本。


I would like to "combine" Fluent Assertion's collection assertions and property assertions, e.g. assert that two IEnumerable's are pairwise-equal using property-by-property (possibly "nested") comparison (i.e. structural equality, in functional language parlance).

Concrete example:

var dic = new Dictionary<int, string>() { {1, "hi"}, {2, "bye" } };
var actual = dic.ToSelectListItems(0).OrderBy(si => si.Text);

var expected = new List<SelectListItem>() {
    new SelectListItem() {Selected = false, Text="bye", Value="2"},
    new SelectListItem() {Selected = false, Text="hi", Value="1"}
};

Here I wrote an extension method ToSelectListItems that converts a Dictionary to an IEnumerable of SelectListItems (from ASP.NET MVC). I want to assert that actual and expected are "structurally" equal, noting that the reference type SelectListItem does not override Equals and thus uses reference equality by default.

Update

Currently using the following hand-rolled solution, still hoping for something better built into FluentAssertions:

public static void ShouldBeStructurallyEqualTo<T, U>(this IEnumerable<T> actual, IEnumerable<U> expected) {
    actual.Should().HaveCount(expected.Count());
    actual.Zip(expected).ForEach(pair => pair.Item1.ShouldHave().AllProperties().IncludingNestedObjects().EqualTo(pair.Item2));
}

(note: Zip here is my own IEnumerable extention which uses Tuple.Create as the default projection)

Update 2

Here are two minimal examples:

public class FooBar {
    public string Foo { get; set; }
    public int Bar { get; set; }
}

public class TestClass {
    [Test]
    public void MinimalExample() {
        List<FooBar> enumerable1 = new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } };
        List<FooBar> enumerable2 = new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } };

        enumerable1.ShouldHave().SharedProperties().IncludingNestedObjects().EqualTo(enumerable2);

        //Test 'TestClass.MinimalExample' failed: System.Reflection.TargetParameterCountException : Parameter count mismatch.
        //    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
        //    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
        //    at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
        //    at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
        //    at FluentAssertions.Assertions.PropertyEqualityValidator.AssertSelectedPropertiesAreEqual(Object subject, Object expected)
        //    at FluentAssertions.Assertions.PropertyEqualityValidator.Validate(UniqueObjectTracker tracker, String parentPropertyName)
        //    at FluentAssertions.Assertions.PropertyEqualityValidator.Validate()
        //    at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject, String reason, Object[] reasonArgs)
        //    at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject)
        //    MiscAssertions.cs(32,0): at TestClass.MinimalExample()
    }

    [Test]
    public void MinimalExample2() {
        IEnumerable<FooBar> enumerable1 = (new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } }).Cast<FooBar>();
        FooBar[] enumerable2 = new [] { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } };

        enumerable1.ShouldHave().SharedProperties().IncludingNestedObjects().EqualTo(enumerable2);

        //Test 'TestClass.MinimalExample2' failed: System.InvalidOperationException : Please specify some properties to include in the comparison.
        //    at FluentAssertions.Assertions.PropertyEqualityValidator.Validate(UniqueObjectTracker tracker, String parentPropertyName)
        //    at FluentAssertions.Assertions.PropertyEqualityValidator.Validate()
        //    at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject, String reason, Object[] reasonArgs)
        //    at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject)
        //    MiscAssertions.cs(52,0): at TestClass.MinimalExample2()
    }
}
解决方案

I have added support for your scenario in the main branch of Fluent Assertions. It will be part of the next version, but it might take us a month or two to accumalate enough changes to warrant another release. If you want, you can grab the source build and run the release.bat to build an intermediate version.

这篇关于如何用流利的-断言结合收集和财产的断言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 09:43