Tôi muốn "kết hợp" xác nhận thu thập thông tin và xác nhận quyền sở hữu của Thông báo xác thực, ví dụ: khẳng định rằng hai số của IEnumerable
tương đương nhau bằng cách sử dụng so sánh thuộc tính theo từng thuộc tính (có thể là "lồng nhau") (nghĩa là sự bình đẳng về cấu trúc, trong ngôn ngữ chức năng).Làm cách nào để kết hợp xác nhận quyền sở hữu bộ sưu tập và thuộc tính bằng cách sử dụng xác nhận thông thạo?
bê tông dụ:
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"}
};
Ở đây tôi đã viết một phương pháp khuyến nông ToSelectListItems
có thể chuyển đổi một Dictionary
một IEnumerable
của SelectListItem
s (từ ASP.NET MVC). Tôi muốn khẳng định rằng actual
và expected
là "có cấu trúc" bằng nhau, lưu ý rằng loại tham chiếu SelectListItem
không ghi đè Equal
s và do đó sử dụng bình đẳng tham chiếu theo mặc định.
Cập nhật
Hiện đang sử dụng giải pháp cuộn bằng tay sau, vẫn hy vọng cho một cái gì đó được xây dựng tốt hơn vào 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));
}
(lưu ý: Zip
đây là của riêng IEnumerable
gia hạn của tôi trong đó sử dụng Tuple.Create
như chiếu mặc định)
Cập nhật 2
Dưới đây là hai ví dụ nhỏ:
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()
}
}
Tôi đã sửa cách giải quyết Stephens để làm việc với các kiểu giá trị tốt, nếu T là một kiểu giá trị nó không hoạt động mà không cần sửa lỗi này: https://gist.github.com/1877672 –
Nó nằm trong phiên bản beta công khai của phiên bản 2.0 http : //fluentassertions.codeplex.com/releases/view/82423 –
Và nó được hỗ trợ như thế nào? Tôi không thể tìm thấy một ví dụ tài liệu. – ferpega